Skip to content

Ensure Image and core palettes are in sync after PA conversion - #9834

Open
akx wants to merge 3 commits into
python-pillow:mainfrom
akx:pa-to-p-to-rgba
Open

Ensure Image and core palettes are in sync after PA conversion#9834
akx wants to merge 3 commits into
python-pillow:mainfrom
akx:pa-to-p-to-rgba

Conversation

@akx

@akx akx commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

While working on #9833, I noticed that an RGBA palette's alphas would be "resurrected" if you converted from PA to P (which retains the RGBA palette in the core im object even if the ImagePalette wrapper is recreated), and then to RGBA.

With this, the "zombie" alpha from the RGBA doesn't appear anymore.
I would suspect this is more the Do What I Mean behavior, because an RGBA palette's alpha values weren't "visible" in a PA image anyway.

Comment thread Tests/test_image_convert.py Outdated
Comment on lines +296 to +297
im.putalpha(Image.frombytes("L", (2, 1), bytes([240, 220])))
assert im.get_flattened_data() == ((0, 240), (1, 220)) # Matches the alpha band

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
im.putalpha(Image.frombytes("L", (2, 1), bytes([240, 220])))
assert im.get_flattened_data() == ((0, 240), (1, 220)) # Matches the alpha band

These lines don't appear relevant.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're meant to show the palette alpha isn't used.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider it pretty foundational that the palette doesn't affect pixel values (without conversion). I'm not sure it needs to be tested here? We already have

im = Image.new("P", (1, 1), 1)
assert im.getpixel((0, 0)) == 1
im.putalpha(2)
assert im.mode == "PA"
assert im.getpixel((0, 0)) == (1, 2)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That test_image_putalpha segment doesn't seem to really cover the contents of the palette.

I don't see how having this here really hurts?

Comment thread src/PIL/Image.py Outdated
Comment on lines +1245 to +1249
from . import ImagePalette

new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB"))
new_im.palette.dirty = True
new_im.load()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from . import ImagePalette
new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB"))
new_im.palette.dirty = True
new_im.load()
new_im.putpalette(im.getpalette())

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied but with explicit "RGB" + comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why explicit "RGB"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because then you don't need to look up getpalette()'s definition to find out that the default is in fact "RGB", and not something that's inferred from im, as I would've initially assumed.

(Or, IOW, Explicit Is Better Than Implicit.)

@akx
akx force-pushed the pa-to-p-to-rgba branch from 9b7eed2 to 215cece Compare July 30, 2026 05:24
akx and others added 2 commits August 10, 2026 21:32
…s dropped)

Co-authored-by: Andrew Murray <radarhere@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants