From 9fd1ec6e1e5699f911ca02edea4ec62a76b3fd4f Mon Sep 17 00:00:00 2001 From: henriquenakashima Date: Mon, 3 Jul 2023 11:57:16 -0400 Subject: [PATCH] Draw external guidelines --- crop_card.py | 67 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/crop_card.py b/crop_card.py index 3a3057b..93387eb 100644 --- a/crop_card.py +++ b/crop_card.py @@ -10,6 +10,8 @@ W_INCHES_EXPECTED = 2.72 H_INCHES_EXPECTED = 3.7 BLEED_INCHES_EXPECTED = 0.12 LEAVE_BLEED_INCHES = 0.04 +CUT_GUIDE_WIDTH_INCHES = 0.006 + BASE_DIR = Path(__file__).parent @@ -59,7 +61,6 @@ def add_cut_guides(im: Image, dpi: float): cut_pixels_int = round(cut_pixels) draw = ImageDraw.Draw(im) LENGTH_CUT_GUIDE_INCHES = 0.06 - CUT_GUIDE_WIDTH_INCHES = 0.006 guide_len = round(LENGTH_CUT_GUIDE_INCHES * dpi) guide_thickness = round(CUT_GUIDE_WIDTH_INCHES * dpi) cut_x_l = cut_pixels_int @@ -98,7 +99,7 @@ def crop(input_filepath: Path) -> Path: print(f'By width dpi is {dpi_by_w} dpi') if dpi_by_h != dpi_by_w: print(f'dpi by height is different: {dpi_by_h} dpi') - crop_pixels = (BLEED_INCHES_EXPECTED - LEAVE_BLEED_INCHES) * dpi_by_w + crop_pixels = BLEED_INCHES_EXPECTED * dpi_by_w - LEAVE_BLEED_INCHES * dpi_by_w crop_pixels_int = round(crop_pixels) print(f'Image is {w} x {h}, will trim {crop_pixels} pixels (rounded to {crop_pixels_int})') @@ -141,8 +142,9 @@ class SheetLayout: self.h_inches = h_inches self.w = self.in_to_px(self.w_inches) self.h = self.in_to_px(self.h_inches) - self.cropped_image_dest_w = self.in_to_px(self.card_w_inches + LEAVE_BLEED_INCHES) - self.cropped_image_dest_h = self.in_to_px(self.card_h_inches + LEAVE_BLEED_INCHES) + self.leave_bleed = self.in_to_px(LEAVE_BLEED_INCHES) + self.cropped_image_dest_w = self.card_w + self.leave_bleed * 2 + self.cropped_image_dest_h = self.card_h + self.leave_bleed * 2 self.spacing_inches = 0.05 self.spacing = self.in_to_px(self.spacing_inches) @@ -164,21 +166,62 @@ class SheetLayout: def in_to_px(self, inches: float) -> float: return round(inches * self.dpi) - def topleft_of_card(self, y_index: int, x_index: int) -> Tuple[int, int]: - assert 0 <= x_index < self.cards_per_row + def top_of_row(self, y_index: int, with_bleed: bool) -> int: assert 0 <= y_index < self.cards_per_column - x = self.blank_space_w + (self.cropped_image_dest_w + self.spacing) * x_index - y = self.blank_space_h + (self.cropped_image_dest_h + self.spacing) * y_index + top = self.blank_space_h + (self.cropped_image_dest_h + self.spacing) * y_index + if not with_bleed: + top += self.leave_bleed + return top + + def bottom_of_row(self, y_index: int, with_bleed: bool) -> int: + if with_bleed: + return self.top_of_row(y_index, True) + self.cropped_image_dest_h + else: + return self.top_of_row(y_index, False) + self.card_h + + def left_of_column(self, x_index: int, with_bleed: bool) -> int: + assert 0 <= x_index < self.cards_per_row + left = self.blank_space_w + (self.cropped_image_dest_w + self.spacing) * x_index + if not with_bleed: + left += self.leave_bleed + return left + + def right_of_column(self, x_index: int, with_bleed: bool) -> int: + if with_bleed: + return self.left_of_column(x_index, True) + self.cropped_image_dest_w + else: + return self.left_of_column(x_index, False) + self.card_w + + def topleft_of_card_with_bleed(self, y_index: int, x_index: int) -> Tuple[int, int]: + x = self.left_of_column(x_index, with_bleed=True) + y = self.top_of_row(y_index, with_bleed=True) return (x, y) def create_sheet(cropped_filepaths: List[Path], sheet_filepath: Path, sheet_layout: SheetLayout): sheet = Image.new('RGB', (sheet_layout.w, sheet_layout.h), 'white') + # Draw external guidelines + draw = ImageDraw.Draw(sheet) + color = 'black' + guide_thickness = sheet_layout.in_to_px(CUT_GUIDE_WIDTH_INCHES) + + for x_index in range(sheet_layout.cards_per_column): + left_x = sheet_layout.left_of_column(x_index, with_bleed=False) + right_x = sheet_layout.right_of_column(x_index, with_bleed=False) + draw.line([(left_x, 0), (left_x, sheet_layout.h)], fill=color, width=guide_thickness) + draw.line([(right_x, 0), (right_x, sheet_layout.h)], fill=color, width=guide_thickness) + + for y_index in range(sheet_layout.cards_per_row): + top_y = sheet_layout.top_of_row(y_index, with_bleed=False) + bottom_y = sheet_layout.bottom_of_row(y_index, with_bleed=False) + draw.line([(0, top_y), (sheet_layout.w, top_y)], fill=color, width=guide_thickness) + draw.line([(0, bottom_y), (sheet_layout.w, bottom_y)], fill=color, width=guide_thickness) + # Draw cards filenames_iter = cropped_filepaths.__iter__() - for y in range(sheet_layout.cards_per_column): - for x in range(sheet_layout.cards_per_row): + for y_index in range(sheet_layout.cards_per_column): + for x_index in range(sheet_layout.cards_per_row): try: filepath = filenames_iter.__next__() except StopIteration: @@ -187,7 +230,9 @@ def create_sheet(cropped_filepaths: List[Path], sheet_filepath: Path, sheet_layo with Image.open(filepath) as card_im: card_im = card_im.resize((sheet_layout.cropped_image_dest_w, sheet_layout.cropped_image_dest_h), resample = Image.Resampling.LANCZOS) - sheet.paste(card_im, sheet_layout.topleft_of_card(y, x)) + sheet.paste(card_im, sheet_layout.topleft_of_card_with_bleed(y_index, x_index)) + + # TODO: Draw internal guidelines # Save sheet sheet.save(sheet_filepath, 'JPEG', dpi=(sheet_layout.dpi, sheet_layout.dpi), quality=100, subsampling=0)