/// <summary> /// Gets data from the scan item field and shows it. /// </summary> private void PopulateForm() { // load scan scanPictureBox.Image = ImageHandling.GetBitmap(scanItem.Image); // load the answers List <KlokanTestDBExpectedAnswer> expectedValues = new List <KlokanTestDBExpectedAnswer>(scanItem.ExpectedValues); TableArrayHandling.DbSetToAnswers(expectedValues, out expectedValuesStudentTable, out expectedValuesAnswerTable); FormTableHandling.DrawAnswers(studentTablePictureBox, expectedValuesStudentTable, 0, FormTableHandling.DrawCross, Color.Black); FormTableHandling.DrawAnswers(answerTable1PictureBox, expectedValuesAnswerTable, 0, FormTableHandling.DrawCross, Color.Black); FormTableHandling.DrawAnswers(answerTable2PictureBox, expectedValuesAnswerTable, 1, FormTableHandling.DrawCross, Color.Black); FormTableHandling.DrawAnswers(answerTable3PictureBox, expectedValuesAnswerTable, 2, FormTableHandling.DrawCross, Color.Black); bool[,,] computedValuesStudentTable; bool[,,] computedValuesAnswerTable; List <KlokanTestDBComputedAnswer> computedValues = new List <KlokanTestDBComputedAnswer>(scanItem.ComputedValues); TableArrayHandling.DbSetToAnswers(computedValues, out computedValuesStudentTable, out computedValuesAnswerTable); FormTableHandling.DrawAnswers(studentTablePictureBox, computedValuesStudentTable, 0, FormTableHandling.DrawCircle, Color.Red); FormTableHandling.DrawAnswers(answerTable1PictureBox, computedValuesAnswerTable, 0, FormTableHandling.DrawCircle, Color.Red); FormTableHandling.DrawAnswers(answerTable2PictureBox, computedValuesAnswerTable, 1, FormTableHandling.DrawCircle, Color.Red); FormTableHandling.DrawAnswers(answerTable3PictureBox, computedValuesAnswerTable, 2, FormTableHandling.DrawCircle, Color.Red); }
/// <summary> /// Extract answer sheet data from the database and display it in the form. /// Returns false if data could not be loaded. /// </summary> private bool PopulateForm() { using (var db = new KlokanDBContext()) { // load sheet data var sheetQuery = from sheet in db.AnswerSheets where sheet.AnswerSheetId == answerSheetId select sheet; KlokanDBAnswerSheet answerSheet = sheetQuery.FirstOrDefault(); if (answerSheet == null) { MessageBox.Show(Properties.Resources.ErrorTextSheetNotFoundInDatabase, Properties.Resources.ErrorCaptionGeneral, MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } var instanceQuery = from instance in db.Instances where instance.InstanceId == answerSheet.InstanceId select instance; KlokanDBInstance currentInstance = instanceQuery.FirstOrDefault(); if (answerSheet == null) { MessageBox.Show(Properties.Resources.ErrorTextSheetNotFoundInDatabase, Properties.Resources.ErrorCaptionGeneral, MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } studentNumber = answerSheet.StudentNumber; // show sheet data studentNumberValueLabel.Text = answerSheet.StudentNumber.ToString(); idValueLabel.Text = answerSheet.AnswerSheetId.ToString(); yearValueLabel.Text = currentInstance.Year.ToString(); categoryValueLabel.Text = currentInstance.Category.ToString(); pointsValueLabel.Text = answerSheet.Points.ToString(); // load scan scanPictureBox.Image = ImageHandling.GetBitmap(answerSheet.Scan); // load answers and draw them var chosenAnswersQuery = from chosenAnswer in db.ChosenAnswers where chosenAnswer.AnswerSheetId == answerSheetId select chosenAnswer; var chosenAnswersList = chosenAnswersQuery.ToList(); if (chosenAnswersList.Count == 0) { MessageBox.Show(Properties.Resources.ErrorTextSheetNotFoundInDatabase, Properties.Resources.ErrorCaptionGeneral, MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } TableArrayHandling.DbSetToAnswers(chosenAnswersList, out chosenAnswers); FormTableHandling.DrawAnswers(table1PictureBox, chosenAnswers, 0, FormTableHandling.DrawCross, Color.Black); FormTableHandling.DrawAnswers(table2PictureBox, chosenAnswers, 1, FormTableHandling.DrawCross, Color.Black); FormTableHandling.DrawAnswers(table3PictureBox, chosenAnswers, 2, FormTableHandling.DrawCross, Color.Black); var correctAnswersQuery = from correctAnswer in db.CorrectAnswers where correctAnswer.InstanceId == answerSheet.InstanceId select correctAnswer; var correctAnswersList = correctAnswersQuery.ToList(); if (correctAnswersList.Count == 0) { MessageBox.Show(Properties.Resources.ErrorTextSheetNotFoundInDatabase, Properties.Resources.ErrorCaptionGeneral, MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } TableArrayHandling.DbSetToAnswers(correctAnswersQuery.ToList(), out correctAnswers); FormTableHandling.DrawAnswers(table1PictureBox, correctAnswers, 0, FormTableHandling.DrawCircle, Color.Red); FormTableHandling.DrawAnswers(table2PictureBox, correctAnswers, 1, FormTableHandling.DrawCircle, Color.Red); FormTableHandling.DrawAnswers(table3PictureBox, correctAnswers, 2, FormTableHandling.DrawCircle, Color.Red); } return(true); }
/// <summary> /// Uses a native library to load an image and extract answers from it. /// Works with both image bytes as well as just an image file path. /// This method is unsafe. /// </summary> /// <param name="sheet">The path to the image containing answers to be extracted as a string or an array of image bytes.</param> /// <param name="studentNumberAnswers">This parameter will contain the student number answers extracted from the student number table.</param> /// <param name="extractedAnswers">This parameter will contain the answers extracted from the answer tables.</param> /// <returns>True if the process has succeeded and false otherwise.</returns> bool ExtractAnswers <T>(T sheet, out bool[,,] studentNumberAnswers, out bool[,,] extractedAnswers) { extractedAnswers = new bool[3, 8, 5]; studentNumberAnswers = new bool[1, 5, 10]; // the first row and the first column of the original tables were removed as they do not contain any answers int studentNumberRows = parameters.StudentTableRows - 1; int studentNumberColumns = parameters.StudentTableColumns - 1; int answerRows = parameters.AnswerTableRows - 1; int answerColumns = parameters.AnswerTableColumns - 1; NumberWrapper numberWrapper = new NumberWrapper(); AnswerWrapper answerWrapper = new AnswerWrapper(); bool success = false; unsafe { bool *numberPtr = numberWrapper.number; bool *answersPtr = answerWrapper.answers; bool *successPtr = &success; string sheetFilename; byte[] sheetImageBytes; // if the sheet has been passed as a filename if ((sheetFilename = sheet as string) != null) { NativeAPIWrapper.extract_answers_path_api(sheetFilename, parameters, numberPtr, answersPtr, successPtr); } // if the sheet has been passed as image bytes else if ((sheetImageBytes = sheet as byte[]) != null) { // the image is saved in PNG (or another format) so we need to convert it to BMP which the library can read Image sheetImage = ImageHandling.GetBitmap(sheetImageBytes); int imageRows = sheetImage.Height; int imageCols = sheetImage.Width; byte[] sheetImageBitmapBytes = ImageHandling.GetImageBytes(sheetImage, ImageFormat.Bmp); sheetImage.Dispose(); fixed(byte *imageBitmapBytesPtr = sheetImageBitmapBytes) { NativeAPIWrapper.extract_answers_image_api(imageBitmapBytesPtr, imageRows, imageCols, parameters, numberPtr, answersPtr, successPtr); } } else { return(false); } if (!success) { return(false); } // convert the student number values from a C-style array of answers to a C# multi-dimensional array for (int row = 0; row < studentNumberRows; row++) { for (int col = 0; col < studentNumberColumns; col++) { if (numberPtr[row * studentNumberColumns + col] == true) { studentNumberAnswers[0, row, col] = true; } else { studentNumberAnswers[0, row, col] = false; } } } // convert the answer table values from a C-style array to a C# multi-dimensional array for (int table = 0; table < parameters.TableCount - 1; table++) { for (int row = 0; row < answerRows; row++) { for (int col = 0; col < answerColumns; col++) { if (answersPtr[table * answerRows * answerColumns + row * answerColumns + col] == true) { extractedAnswers[table, row, col] = true; } else { extractedAnswers[table, row, col] = false; } } } } } return(true); }