From a6352f2c5dabb283267a0ae3c0be0d604c725673 Mon Sep 17 00:00:00 2001 From: Chris Dailey Date: Mon, 1 Jul 2024 13:05:02 -0400 Subject: [PATCH] Adds an 'image overlay' feature. This adds an `--overlay` argument to specify a file path. That image is then overlaid on top of each card image as they're plotted to the result png or pdf. --- README.md | 1 + mtgproxies/print_cards.py | 38 +++++++++++++++++++++++++++++++++++++- print.py | 8 ++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 92c9293..4fd0e76 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ optional arguments: add crop marks (default: True) --faces {all,front,back} which faces to print (default: all) + --overlay OVERLAY image file to overlay on every card ``` ### convert diff --git a/mtgproxies/print_cards.py b/mtgproxies/print_cards.py index 6033364..a28a9b8 100644 --- a/mtgproxies/print_cards.py +++ b/mtgproxies/print_cards.py @@ -26,6 +26,7 @@ def print_cards_matplotlib( interpolation: str | None = "lanczos", dpi: int = 600, background_color=None, + overlay: str | Path | None = None, ): """Print a list of cards to a pdf file. @@ -35,12 +36,14 @@ def print_cards_matplotlib( papersize: Size of the paper in inches. Defaults to A4. cardsize: Size of a card in inches. border_crop: How many pixel to crop from the border of each card. + overlay: A path to an image file to overlay on each card. """ # Cards per figure N = np.floor(papersize / cardsize).astype(int) if N[0] == 0 or N[1] == 0: raise ValueError(f"Paper size too small: {papersize}") offset = (papersize - _occupied_space(cardsize, N, border_crop, closed=True)) / 2 + aspect = papersize[1] / papersize[0] # Ensure directory exists filepath = Path(filepath) @@ -52,6 +55,15 @@ def print_cards_matplotlib( else: saver = SplitPages + # Initialize overlay + overlay_image = None + + if overlay is not None: + overlay_path = Path(overlay) + if not overlay_path.is_file(): + raise ValueError(f"Overlay specified is not a file: {overlay}") + overlay_image = plt.imread(overlay_path) + with saver(filepath) as saver, tqdm(total=len(images), desc="Plotting cards") as pbar: while len(images) > 0: fig = plt.figure(figsize=papersize) @@ -82,9 +94,19 @@ def print_cards_matplotlib( plt.imshow( img, extent=extent, - aspect=papersize[1] / papersize[0], + aspect=aspect, interpolation=interpolation, ) + + # Add overlay on top of card image + if overlay_image is not None: + plt.imshow( + overlay_image, + extent=extent, + aspect=aspect, + interpolation=interpolation, + ) + pbar.update(1) plt.xlim(0, 1) @@ -105,6 +127,7 @@ def print_cards_fpdf( border_crop: int = 14, background_color: tuple[int, int, int] = None, cropmarks: bool = True, + overlay: str | Path | None = None, ) -> None: """Print a list of cards to a pdf file. @@ -114,6 +137,7 @@ def print_cards_fpdf( papersize: Size of the paper in inches. Defaults to A4. cardsize: Size of a card in inches. border_crop: How many pixel to crop from the border of each card. + overlay: A path to an image file to overlay on each card. """ from fpdf import FPDF @@ -128,6 +152,14 @@ def print_cards_fpdf( filepath = Path(filepath) filepath.parent.mkdir(parents=True, exist_ok=True) + # Initialize overlay + overlay_path = None + + if overlay is not None: + overlay_path = Path(overlay) + if not overlay_path.is_file(): + raise ValueError(f"Overlay specified is not a file: {overlay}") + # Initialize PDF pdf = FPDF(orientation="P", unit="mm", format="A4") @@ -161,6 +193,10 @@ def print_cards_fpdf( # Plot image pdf.image(cropped_image, x=lower[0], y=lower[1], w=size[0], h=size[1]) + # Plot overlay on top of card image + if overlay_path is not None: + pdf.image(overlay_path, x=lower[0], y=lower[1], w=size[0], h=size[1]) + if cropmarks and ((i + 1) % cards_per_sheet == 0 or i + 1 == len(images)): # If this was the last card on a page, add crop marks pdf.set_line_width(0.05) diff --git a/print.py b/print.py index 340a9c7..ac379ef 100644 --- a/print.py +++ b/print.py @@ -60,6 +60,12 @@ def papersize(string: str) -> np.ndarray: choices=["all", "front", "back"], default="all", ) + parser.add_argument( + "--overlay", + help="image file to overlay on every card", + type=str, + default=None, + ) args = parser.parse_args() # Parse decklist @@ -84,6 +90,7 @@ def papersize(string: str) -> np.ndarray: border_crop=args.border_crop, background_color=background_color, cropmarks=args.cropmarks, + overlay=args.overlay, ) else: print_cards_matplotlib( @@ -94,4 +101,5 @@ def papersize(string: str) -> np.ndarray: dpi=args.dpi, border_crop=args.border_crop, background_color=args.background, + overlay=args.overlay, )