Fix white lines, generate images for border printing
This commit is contained in:
parent
088181085e
commit
b0eabd1297
3 changed files with 49 additions and 27 deletions
|
|
@ -2,13 +2,18 @@ from pathlib import Path
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from base_proxy import LEAVE_BLEED_INCHES
|
from base_proxy import BASE_DIR
|
||||||
from sheet_layout import SheetLayout, CardImageTransfer
|
from sheet_layout import SheetLayout, CardImageTransfer
|
||||||
|
|
||||||
|
|
||||||
W_INCHES_EXPECTED = 2.72
|
W_INCHES_EXPECTED = 2.72
|
||||||
H_INCHES_EXPECTED = 3.7
|
H_INCHES_EXPECTED = 3.7
|
||||||
BLEED_INCHES_EXPECTED = 0.12
|
|
||||||
|
SAVE_INTERMEDIATE_FOR_DEBUG = False
|
||||||
|
|
||||||
|
|
||||||
|
def make_intermediate_name(input_path: Path, infix: str):
|
||||||
|
return BASE_DIR / 'cropped_cards' / f'{input_path.stem}.{infix}.jpg'
|
||||||
|
|
||||||
|
|
||||||
class InputCardImage:
|
class InputCardImage:
|
||||||
|
|
@ -28,30 +33,43 @@ class InputCardImage:
|
||||||
if dpi_by_h != dpi_by_w:
|
if dpi_by_h != dpi_by_w:
|
||||||
print(f'By height dpi is different: {dpi_by_h} dpi')
|
print(f'By height dpi is different: {dpi_by_h} dpi')
|
||||||
self.input_dpi = dpi_by_w
|
self.input_dpi = dpi_by_w
|
||||||
self.original_im = im
|
self.original_im = rgb_im
|
||||||
|
|
||||||
def get_cropped_and_resized(self, layout: SheetLayout, transfer: CardImageTransfer) -> Image:
|
def get_cropped_and_resized(self, layout: SheetLayout, transfer: CardImageTransfer) -> Image:
|
||||||
new_dpi = layout.dpi
|
new_dpi = layout.dpi
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
im = self.original_im
|
im = self.original_im
|
||||||
|
print(f'Input is {im.size[0]} x {im.size[1]}')
|
||||||
|
|
||||||
# Resize to match sheet DPI
|
# Resize to match sheet DPI
|
||||||
new_w = layout.in_to_px(W_INCHES_EXPECTED)
|
new_w = layout.in_to_px(W_INCHES_EXPECTED)
|
||||||
new_h = layout.in_to_px(H_INCHES_EXPECTED)
|
new_h = layout.in_to_px(H_INCHES_EXPECTED)
|
||||||
|
print(f'Resized input to {new_w} x {new_h}')
|
||||||
im = im.resize((new_w, new_h), resample=Image.Resampling.LANCZOS)
|
im = im.resize((new_w, new_h), resample=Image.Resampling.LANCZOS)
|
||||||
|
if SAVE_INTERMEDIATE_FOR_DEBUG:
|
||||||
|
im.save(make_intermediate_name(self.path, 'step1resize'), 'JPEG', dpi=(layout.dpi, layout.dpi), quality=100, subsampling=0)
|
||||||
|
|
||||||
# Crop
|
# Crop
|
||||||
top_bleed, bottom_bleed, left_bleed, right_bleed = transfer.bleeds
|
left = (new_w - layout.card_w) // 2
|
||||||
crop_pixels_leaving_bleed = layout.in_to_px(BLEED_INCHES_EXPECTED - LEAVE_BLEED_INCHES)
|
right = left + layout.card_w
|
||||||
crop_pixels_no_bleed = layout.in_to_px(BLEED_INCHES_EXPECTED)
|
top = (new_h - layout.card_h) // 2
|
||||||
top_crop = crop_pixels_leaving_bleed if top_bleed else crop_pixels_no_bleed
|
bottom = top + layout.card_h
|
||||||
bottom_crop = crop_pixels_leaving_bleed if bottom_bleed else crop_pixels_no_bleed
|
if transfer.bleeds[0]:
|
||||||
left_crop = crop_pixels_leaving_bleed if left_bleed else crop_pixels_no_bleed
|
top -= layout.leave_bleed
|
||||||
right_crop = crop_pixels_leaving_bleed if right_bleed else crop_pixels_no_bleed
|
if transfer.bleeds[1]:
|
||||||
|
bottom += layout.leave_bleed
|
||||||
|
if transfer.bleeds[2]:
|
||||||
|
left -= layout.leave_bleed
|
||||||
|
if transfer.bleeds[3]:
|
||||||
|
right += layout.leave_bleed
|
||||||
|
|
||||||
# Crop
|
# Crop
|
||||||
crop_box = (left_crop, top_crop, new_w - right_crop, new_h - bottom_crop)
|
crop_box = (left, top, right, bottom)
|
||||||
|
print(f'Cropped box {crop_box}')
|
||||||
im = im.crop(crop_box)
|
im = im.crop(crop_box)
|
||||||
|
|
||||||
|
if SAVE_INTERMEDIATE_FOR_DEBUG:
|
||||||
|
im.save(make_intermediate_name(self.path, 'step2crop'), 'JPEG', dpi=(layout.dpi, layout.dpi), quality=100, subsampling=0)
|
||||||
|
|
||||||
return im
|
return im
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import util
|
||||||
|
|
||||||
|
|
||||||
CUT_GUIDE_WIDTH_INCHES = 0.006
|
CUT_GUIDE_WIDTH_INCHES = 0.006
|
||||||
LENGTH_CUT_GUIDE_INCHES = 0.06
|
LENGTH_CUT_GUIDE_INCHES = 0.04
|
||||||
|
|
||||||
|
|
||||||
def gather_images(directory: Path) -> List[Path]:
|
def gather_images(directory: Path) -> List[Path]:
|
||||||
|
|
@ -43,7 +43,7 @@ def create_sheet(input_cards: List[InputCardImage], sheet_filepath: Path, layout
|
||||||
color = 'black'
|
color = 'black'
|
||||||
guide_thickness = layout.in_to_px(CUT_GUIDE_WIDTH_INCHES)
|
guide_thickness = layout.in_to_px(CUT_GUIDE_WIDTH_INCHES)
|
||||||
|
|
||||||
for x_index in range(layout.cards_per_column):
|
for x_index in range(layout.cards_per_row):
|
||||||
left_x = layout.card_area_left_xs[x_index]
|
left_x = layout.card_area_left_xs[x_index]
|
||||||
right_x = layout.card_area_right_xs[x_index]
|
right_x = layout.card_area_right_xs[x_index]
|
||||||
min_y = layout.min_padding
|
min_y = layout.min_padding
|
||||||
|
|
@ -51,7 +51,7 @@ def create_sheet(input_cards: List[InputCardImage], sheet_filepath: Path, layout
|
||||||
draw.line([(left_x, min_y), (left_x, max_y)], fill=color, width=guide_thickness)
|
draw.line([(left_x, min_y), (left_x, max_y)], fill=color, width=guide_thickness)
|
||||||
draw.line([(right_x, min_y), (right_x, max_y)], fill=color, width=guide_thickness)
|
draw.line([(right_x, min_y), (right_x, max_y)], fill=color, width=guide_thickness)
|
||||||
|
|
||||||
for y_index in range(layout.cards_per_row):
|
for y_index in range(layout.cards_per_column):
|
||||||
top_y = layout.card_area_top_ys[y_index]
|
top_y = layout.card_area_top_ys[y_index]
|
||||||
bottom_y = layout.card_area_bottom_ys[y_index]
|
bottom_y = layout.card_area_bottom_ys[y_index]
|
||||||
min_x = layout.min_padding
|
min_x = layout.min_padding
|
||||||
|
|
@ -107,7 +107,7 @@ def main():
|
||||||
|
|
||||||
all_input_cards = [InputCardImage(p) for p in all_input_cards_paths]
|
all_input_cards = [InputCardImage(p) for p in all_input_cards_paths]
|
||||||
|
|
||||||
layout = sheet_layout.letter_portrait_3x3_sheet_layout()
|
layout = sheet_layout.letter_portrait_3x3_sheet_layout_120milborder()
|
||||||
sheets_dir = BASE_DIR / 'sheets'
|
sheets_dir = BASE_DIR / 'sheets'
|
||||||
sheets_dir.mkdir(parents=True, exist_ok=True)
|
sheets_dir.mkdir(parents=True, exist_ok=True)
|
||||||
total_sheet_number = math.ceil(len(all_input_cards) / layout.cards_per_sheet)
|
total_sheet_number = math.ceil(len(all_input_cards) / layout.cards_per_sheet)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class CardImageTransfer:
|
||||||
|
|
||||||
|
|
||||||
class SheetLayout:
|
class SheetLayout:
|
||||||
def __init__(self, dpi: int, w_inches: float, h_inches: float, internal_bleed: bool):
|
def __init__(self, dpi: int, w_mils: int, h_mils: int, internal_bleed: bool, paper_border_mils: int):
|
||||||
self.dpi = dpi
|
self.dpi = dpi
|
||||||
|
|
||||||
self.card_w_inches = CARD_W_INCHES
|
self.card_w_inches = CARD_W_INCHES
|
||||||
|
|
@ -20,17 +20,14 @@ class SheetLayout:
|
||||||
self.card_w = self.in_to_px(self.card_w_inches)
|
self.card_w = self.in_to_px(self.card_w_inches)
|
||||||
self.card_h = self.in_to_px(self.card_h_inches)
|
self.card_h = self.in_to_px(self.card_h_inches)
|
||||||
|
|
||||||
self.w_inches = w_inches
|
self.w = self.mil_to_px(w_mils)
|
||||||
self.h_inches = h_inches
|
self.h = self.mil_to_px(h_mils)
|
||||||
self.w = self.in_to_px(self.w_inches)
|
|
||||||
self.h = self.in_to_px(self.h_inches)
|
|
||||||
self.leave_bleed = self.in_to_px(LEAVE_BLEED_INCHES)
|
self.leave_bleed = self.in_to_px(LEAVE_BLEED_INCHES)
|
||||||
|
|
||||||
self.spacing_inches = 0.05 if internal_bleed else 0
|
self.spacing_inches = 0.05 if internal_bleed else 0
|
||||||
self.spacing = self.in_to_px(self.spacing_inches)
|
self.spacing = self.in_to_px(self.spacing_inches)
|
||||||
|
|
||||||
self.min_padding_inches = 0.12
|
self.min_padding = self.mil_to_px(paper_border_mils)
|
||||||
self.min_padding = self.in_to_px(self.min_padding_inches)
|
|
||||||
|
|
||||||
paste_area_left_xs = []
|
paste_area_left_xs = []
|
||||||
paste_area_right_xs = []
|
paste_area_right_xs = []
|
||||||
|
|
@ -124,9 +121,12 @@ class SheetLayout:
|
||||||
|
|
||||||
print(self.__dict__)
|
print(self.__dict__)
|
||||||
|
|
||||||
def in_to_px(self, inches: float) -> float:
|
def in_to_px(self, inches: float) -> int:
|
||||||
return round(inches * self.dpi)
|
return round(inches * self.dpi)
|
||||||
|
|
||||||
|
def mil_to_px(self, mils: int) -> int:
|
||||||
|
return mils * self.dpi // 1000
|
||||||
|
|
||||||
def create_card_image_transfer(self, y_index: int, x_index: int) -> CardImageTransfer:
|
def create_card_image_transfer(self, y_index: int, x_index: int) -> CardImageTransfer:
|
||||||
top_row = y_index == 0
|
top_row = y_index == 0
|
||||||
bottom_row = y_index == self.cards_per_column - 1
|
bottom_row = y_index == self.cards_per_column - 1
|
||||||
|
|
@ -144,10 +144,14 @@ class SheetLayout:
|
||||||
return CardImageTransfer((paste_x, paste_y), bleeds)
|
return CardImageTransfer((paste_x, paste_y), bleeds)
|
||||||
|
|
||||||
|
|
||||||
def letter_portrait_3x3_sheet_layout() -> SheetLayout:
|
def letter_portrait_3x3_sheet_layout_120milborder() -> SheetLayout:
|
||||||
return SheetLayout(1200, 8.5, 11, False)
|
return SheetLayout(1200, 8500 - 2 * 120, 11000 - 2 * 120, False, 0)
|
||||||
|
|
||||||
|
|
||||||
def letter_landscape_2x4_sheet_layout() -> SheetLayout:
|
def letter_portrait_3x3_sheet_layout_120milborderless() -> SheetLayout:
|
||||||
return SheetLayout(1200, 11, 8.5, False)
|
return SheetLayout(1200, 8500, 11000, False, 120)
|
||||||
|
|
||||||
|
|
||||||
|
def letter_landscape_2x4_sheet_layout_120milborderless() -> SheetLayout:
|
||||||
|
return SheetLayout(1200, 11000, 8500, False, 120)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue