Skip to content

[WIP] Fix exif text overlap with color palette in border#2

Merged
Rustymage merged 1 commit into
mainfrom
copilot/fix-exif-text-overlap-with-palette
May 1, 2026
Merged

[WIP] Fix exif text overlap with color palette in border#2
Rustymage merged 1 commit into
mainfrom
copilot/fix-exif-text-overlap-with-palette

Conversation

Copy link
Copy Markdown

Copilot AI commented May 1, 2026

  • Add max_width parameter to draw_exif in border.py to shrink fonts when text would overlap the palette
  • Update main.py to calculate palette position/size before calling draw_exif, compute exif_max_width, and pass it to draw_exif
  • Run validation
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.
  • As a result, the exif text can extend into and over the palette region.

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
  • main.pyprocess_image function

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

User: when using the environment variable medium with exif data and color palette, sometimes the exif data prints over the color palette rather than shrinking further.

Assistant: Now I have a clear picture of the bug. Here's the root cause and fix:


Root Cause

When using --border_type m (medium) with both --exif and --palette:

  1. draw_exif draws text horizontally (left-to-right) starting at x = border.left, because medium is not in the centered list (POLAROID, LARGE, INSTAGRAM). The font multiplier is 0.5 of border.bottom — larger than for centered layouts.
  2. load_image_color_palette + overlay_palette then places a color palette in the bottom-right of the border.
  3. The exif text is drawn before the palette and has no knowledge of how much horizontal space the palette will occupy — so it can extend into (and over) the palette region.

The exif drawing code in border.py (draw_exif) has no max_width constraint, and t...

This pull request was created from Copilot chat.

@Rustymage Rustymage marked this pull request as ready for review May 1, 2026 21:10
@Rustymage Rustymage merged commit aec8d97 into main May 1, 2026
1 check failed
Copilot stopped work on behalf of Rustymage due to an error May 1, 2026 21:11
Copilot AI requested a review from Rustymage May 1, 2026 21:11
@Rustymage Rustymage deleted the copilot/fix-exif-text-overlap-with-palette branch May 1, 2026 21:20
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