Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageOps.expand error with tuple border #5614

Closed
ProgrammerPeter opened this issue Jul 16, 2021 · 2 comments · Fixed by #5615
Closed

ImageOps.expand error with tuple border #5614

ProgrammerPeter opened this issue Jul 16, 2021 · 2 comments · Fixed by #5615

Comments

@ProgrammerPeter
Copy link

ProgrammerPeter commented Jul 16, 2021

What did you do?

Call ImageOps.expand with a tuple border.

What did you expect to happen?

Input image will be expanded.

What actually happened?

It raises a TypeError that says in draw_rectangle function, width requires an integer but got a tuple.

What are your OS, Python and Pillow versions?

  • OS: Ubuntu
  • Python: 3.7.5
  • Pillow: 8.3.1

I find in PR #5552 ImageOps.expand was modified and add two lines of code to draw the output, which are not necessary.
I guess if it is code for debug. If not, please notice that border may be a tuple and can not be passed to draw.rectangle as width.

def expand(image, border=0, fill=0):
    """
    Add border to the image
    :param image: The image to expand.
    :param border: Border width, in pixels.
    :param fill: Pixel fill value (a color value).  Default is 0 (black).
    :return: An image.
    """
    left, top, right, bottom = _border(border)
    width = left + image.size[0] + right
    height = top + image.size[1] + bottom
    color = _color(fill, image.mode)
    if image.mode == "P" and image.palette:
        out = Image.new(image.mode, (width, height))
        out.putpalette(image.palette)
        out.paste(image, (left, top))

        draw = ImageDraw.Draw(out)
        draw.rectangle((0, 0, width, height), outline=color, width=border) # TypeError from here
    else:
        out = Image.new(image.mode, (width, height), color)
        out.paste(image, (left, top))
    return out
@ProgrammerPeter
Copy link
Author

@radarhere may know this.

@radarhere
Copy link
Member

Pillow/src/PIL/ImageOps.py

Lines 402 to 403 in 696b82e

draw = ImageDraw.Draw(out)
draw.rectangle((0, 0, width - 1, height - 1), outline=color, width=border)

It's not for debugging purposes. These lines are there to draw the fill color. If color is an RGB color, then it needs to be looked up in the image palette. This needs to be done on a new palette (to avoid modifying the original image if an additional paletter entry needs to be allocated). Without this draw operation, the border color would just be the zero index.

I've created #5615 to resolve this issue by changing the strategy. Instead, the PR creates a copy of the palette, calculates the palette index from that and uses it for the background color, and then attaches the new palette to the output image.

@radarhere radarhere changed the title Bug in ImageOps.expand ImageOps.expand error with tuple border Jul 16, 2021
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 a pull request may close this issue.

2 participants