diff --git a/tests/test_scans.py b/tests/test_scans.py index 5b61b30be5ecd090148589fe60acdf056279e856..79a4e7aaab2bcca76b8f09cd578f62f712ed94b5 100644 --- a/tests/test_scans.py +++ b/tests/test_scans.py @@ -291,15 +291,15 @@ def test_realign_image(datadir, file_name): test_file = os.path.join(datadir, dir_name, file_name) test_image = np.array(PIL.Image.open(test_file)) - correct_corner_markers = [(58, 58), (1180, 58), (58, 1694), (1180, 1694)] + correct_corner_markers = [(59, 59), (1181, 59), (59, 1694), (1181, 1694)] result_image, result_corner_markers = scans.realign_image(test_image) assert result_corner_markers is not None for i in range(4): diff = np.absolute(np.subtract(correct_corner_markers[i], result_corner_markers[i])) - assert diff[0] < epsilon - assert diff[1] < epsilon + assert diff[0] <= epsilon + assert diff[1] <= epsilon def test_incomplete_reference_realign_image(datadir): diff --git a/zesje/api/exams.py b/zesje/api/exams.py index a1c449a05bd1ad5d5a1f50a75c7e3698d66114e5..83dd18b52229ab84363cd29a877c4cb832c34f31 100644 --- a/zesje/api/exams.py +++ b/zesje/api/exams.py @@ -9,14 +9,9 @@ from flask_restful import Resource, reqparse from werkzeug.datastructures import FileStorage from sqlalchemy.orm import selectinload -from ..pdf_generation import generate_pdfs, output_pdf_filename_format, join_pdfs, page_is_size +from ..pdf_generation import PAGE_FORMATS, generate_pdfs, output_pdf_filename_format, join_pdfs, page_is_size from ..database import db, Exam, ExamWidget, Submission -PAGE_FORMATS = { - "A4": (595.276, 841.89), - "US letter": (612, 792), -} - def _get_exam_dir(exam_id): return os.path.join( diff --git a/zesje/pdf_generation.py b/zesje/pdf_generation.py index 09bf9641bd13e631eb02a163f69ef2959b7955d6..e4b3c2ece43bfb237c09cdfc05f2bca60507c336 100644 --- a/zesje/pdf_generation.py +++ b/zesje/pdf_generation.py @@ -10,6 +10,19 @@ from reportlab.pdfgen import canvas output_pdf_filename_format = '{0:05d}.pdf' +# the size of the markers in points +MARKER_FORMAT = { + "margin": 10 * mm, + "marker_line_length": 8 * mm, + "marker_line_width": 1 * mm, + "bar_length": 40 * mm +} + +PAGE_FORMATS = { + "A4": (595.276, 841.89), + "US letter": (612, 792), +} + def generate_pdfs(exam_pdf_file, exam_id, copy_nums, output_paths, id_grid_x, id_grid_y, datamatrix_x, datamatrix_y, cb_data=None): @@ -318,15 +331,14 @@ def _add_corner_markers_and_bottom_bar(canv, pagesize): """ page_width = pagesize[0] page_height = pagesize[1] - margin = 10 * mm - marker_line_length = 8 * mm - bar_length = 40 * mm + marker_line_length = MARKER_FORMAT["marker_line_length"] + bar_length = MARKER_FORMAT["bar_length"] # Calculate coordinates offset from page edge - left = margin - bottom = margin - right = page_width - margin - top = page_height - margin + left = MARKER_FORMAT["margin"] + bottom = MARKER_FORMAT["margin"] + right = page_width - MARKER_FORMAT["margin"] + top = page_height - MARKER_FORMAT["margin"] # Calculate start and end coordinates of bottom bar bar_start = page_width / 2 - bar_length / 2 diff --git a/zesje/scans.py b/zesje/scans.py index 8addf7ab033a93d3809734760ae5988dec36ec45..9fbee694be950c006c6e24d57fe61345ee16e7a8 100644 --- a/zesje/scans.py +++ b/zesje/scans.py @@ -19,6 +19,8 @@ from .images import guess_dpi, get_box, fix_corner_markers from .factory import make_celery from .pregrader import add_feedback_to_solution +from .pdf_generation import MARKER_FORMAT, PAGE_FORMATS + ExtractedBarcode = namedtuple('ExtractedBarcode', ['token', 'copy', 'page']) ExamMetadata = namedtuple('ExamMetadata', ['token', 'barcode_coords']) @@ -791,7 +793,7 @@ def check_corner_keypoints(image_array, keypoints): def realign_image(image_array, keypoints=None, - reference_keypoints=None): + reference_keypoints=None, page_format="A4"): """ Transform the image so that the keypoints match the reference. @@ -815,7 +817,7 @@ def realign_image(image_array, keypoints=None, New keypoints properly aligned. """ - if(keypoints is None): + if(not keypoints): keypoints = find_corner_marker_keypoints(image_array) check_corner_keypoints(image_array, keypoints) @@ -823,8 +825,10 @@ def realign_image(image_array, keypoints=None, keypoints = fix_corner_markers(keypoints, image_array.shape) # use standard keypoints if no custom ones are provided - if (reference_keypoints is None): - reference_keypoints = [(59, 59), (1179, 59), (59, 1693), (1179, 1693)] + if (not reference_keypoints): + # reference_keypoints = [(59, 59), (1179, 59), (59, 1693), (1179, 1693)] + dpi = guess_dpi(image_array) + reference_keypoints = generate_perfect_corner_markers(page_format, dpi) if (len(reference_keypoints) != 4): # this function assumes that the template has the same dimensions as the input image @@ -848,3 +852,15 @@ def realign_image(image_array, keypoints=None, return_keypoints = fix_corner_markers(return_keypoints, return_image.shape) return return_image, return_keypoints + + +def generate_perfect_corner_markers(format="A4", dpi=200): + left_x = MARKER_FORMAT["margin"]/72 * dpi + top_y = MARKER_FORMAT["margin"]/72 * dpi + right_x = (PAGE_FORMATS[format][0] - MARKER_FORMAT["margin"])/72 * dpi + bottom_y = (PAGE_FORMATS[format][1] - MARKER_FORMAT["margin"])/72 * dpi + + return [(left_x, top_y), + (right_x, top_y), + (left_x, bottom_y), + (right_x, bottom_y)]