Skip to content

Fix exif text overlapping color palette on medium border type#3

Merged
Rustymage merged 2 commits into
mainfrom
copilot/fix-exif-text-overlap
May 1, 2026
Merged

Fix exif text overlapping color palette on medium border type#3
Rustymage merged 2 commits into
mainfrom
copilot/fix-exif-text-overlap

Conversation

Copy link
Copy Markdown

Copilot AI commented May 1, 2026

When --exif and --palette are used together on non-centered border types (small/medium), exif text was drawn without awareness of the palette's horizontal position, causing overlap.

Changes

border.py

  • Added optional max_width: int = None parameter to draw_exif
  • When max_width is set and the layout is non-centered, iteratively shrinks font_size and heading_font_size until all exif text lines fit within the available width
  • Moved ImageFont/ImageDraw imports to module level; ImageDraw.Draw constructed once outside the shrink loop

main.py

  • Moved palette size/position calculation (palette_size, palette_x, palette_y) to before the exif drawing step
  • Computes exif_max_width = palette_x - border.left and passes it to draw_exif
  • Image compositing order (exif drawn before palette overlay) is unchanged
exif_max_width = None

if add_palette:
    palette_size = round(border.bottom / 3)
    color_palette = load_image_color_palette(img, palette_size)
    palette_x = img_with_border.width - border.right - color_palette.width
    palette_y = img_with_border.height - round(border.bottom / 2) - round(color_palette.height / 2)
    exif_max_width = palette_x - border.left  # space available before palette

if add_exif:
    ...
    img_with_border = draw_exif(..., max_width=exif_max_width)

if add_palette:
    img_with_border = overlay_palette(img=img_with_border, color_palette=color_palette, offset=(palette_x, palette_y))
Original prompt

Problem

When using --border_type m (medium) with both --exif and --palette flags, the exif data text is drawn over the color palette instead of shrinking to fit the available space.

Root cause:

  • draw_exif in border.py draws text horizontally (left-to-right) for non-centered border types (small, medium).
  • The font size is only scaled to fit the height of the border, with no constraint on width.
  • The color palette is placed in the bottom-right of the border, but draw_exif has no knowledge of how much horizontal space the palette occupies.
  • In main.py, the palette is calculated after draw_exif is called, so there is no way to pass width constraints to the exif drawing step.

Fix

1. border.py — Add max_width parameter to draw_exif

Add an optional max_width parameter to draw_exif. When provided (and the layout is non-centered), iteratively reduce the font sizes until all exif text lines fit within max_width.

def draw_exif(img: Image, exif: dict, border: Border, fontpath: str, boldfontpath: str, max_width: int = None) -> Image:
    centered = border.border_type in (BorderType.POLAROID, BorderType.LARGE, BorderType.INSTAGRAM)
    multiplier = 0.2 if centered else 0.5
    font_size = tm.get_optimal_font_size("Test string", border.bottom * multiplier, fontpath)
    heading_font_size = tm.get_optimal_font_size("Test string", border.bottom * (multiplier + 0.02), boldfontpath)

    # If a max_width is set (e.g. palette is present), shrink fonts until all exif lines fit
    if max_width and not centered:
        from PIL import ImageFont, ImageDraw
        exif_lines = [
            f"{exif['Make']} {exif['Model']}",
            f"{exif['LensMake']} {exif['LensModel']}",
            f"{exif['FocalLength']}  {exif['FNumber']}  {exif['ISOSpeedRatings']}  {exif['ExposureTime']}",
        ]
        while font_size > 1:
            test_heading = ImageFont.truetype(boldfontpath, heading_font_size)
            test_font = ImageFont.truetype(fontpath, font_size)
            dummy = ImageDraw.Draw(img)
            widths = [dummy.textlength(exif_lines[0], font=test_heading)] + \
                     [dummy.textlength(line, font=test_font) for line in exif_lines[1:]]
            if max(widths) <= max_width:
                break
            font_size -= 1
            heading_font_size = max(1, heading_font_size - 1)

    font = tm.create_font(font_size, fontpath)
    heading_font = tm.create_font(heading_font_size, boldfontpath)
    # ... rest of function unchanged

2. main.py — Calculate palette width before calling draw_exif, pass max_width

  • Move the palette size and position calculation to before the exif drawing step.
  • Compute exif_max_width = palette_x - border.left (the horizontal space available for text).
  • Pass max_width=exif_max_width into draw_exif.
  • Keep the actual overlay_palette call after exif drawing (order of image compositing unchanged).
exif_max_width = None

if add_palette:
    palette_size = round(border.bottom / 3)
    color_palette = load_image_color_palette(img, palette_size)
    palette_x = img_with_border.width - border.right - color_palette.width
    palette_y = img_with_border.height - round(border.bottom / 2) - round(color_palette.height / 2)
    exif_max_width = palette_x - border.left  # space available for exif text

if add_exif:
    exif = get_exif(img)
    if exif:
        ...
        img_with_border = draw_exif(img_with_border, exif, border, font_path, bold_font_path, max_width=exif_max_width)
        save_as = f'{save_as}_exif'

if add_palette:
    img_with_border = overlay_palette(img=img_with_border,
                                      color_palette=color_palette,
                                      offset=(palette_x, palette_y))
    save_as = f'{save_as}_palette'

Files to change

  • border.pydraw_exif function: add optional max_width parameter and font-shrinking loop
  • main.pyprocess_image function: move palette size/position calculation before exif drawing, compute and pass exif_max_width

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: when using color palette and exfi environment variables the exif text can overlap with the color palette and should not.

Assistant: PR #2 — Fix exif text overlap with color palette in border has already been merged into main about 13 minutes ago! 🎉

Here's a summary of what was implemented:

Changes Made

border.pydraw_exif function:

  • Added an optional max_width parameter
  • When max_width is provided and the layout is non-centered (small/medium border types), the font sizes are iteratively reduced until all EXIF text lines fit within the available horizontal space

main.pyprocess_image function:

  • Moved palette size and position calculation to before the EXIF draw...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Fix exif data text overlapping with color palette Fix exif text overlapping color palette on medium border type May 1, 2026
Copilot AI requested a review from Rustymage May 1, 2026 21:27
@Rustymage Rustymage marked this pull request as ready for review May 1, 2026 21:35
@Rustymage Rustymage merged commit d6dd217 into main May 1, 2026
@Rustymage Rustymage deleted the copilot/fix-exif-text-overlap branch May 2, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants