Skip to content

Reproduce partially transparent affine backgrounds exactly#212

Merged
kipcole9 merged 1 commit into
elixir-image:mainfrom
hlindset:fix/exact-affine-background-fill
Jul 9, 2026
Merged

Reproduce partially transparent affine backgrounds exactly#212
kipcole9 merged 1 commit into
elixir-image:mainfrom
hlindset:fix/exact-affine-background-fill

Conversation

@hlindset

@hlindset hlindset commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

A partially transparent :background in affine/3, rotate/3, translate/4 and shear/4 came back distorted because libvips injects it raw into a premultiplied space, so the output unpremultiply scaled the color bands by max_alpha / alpha:

Image.affine(image, matrix, background: [10, 20, 30, 40])
# fill came out [63, 127, 191, 40]

Now the image and background are premultiplied first and the affine runs with premultiplied: true.

Note: Since vips_rotate() doesn't expose the premultiplied option, rotate/3 sends alpha images through affine/3instead. vips_rotate() is a wrapper over vips_affine() under the hood, so this is lossless.

@kipcole9

kipcole9 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

I knew that I was handling pre-multiplied badly - you fixing this area is really fabulous, thank you.

@kipcole9 kipcole9 merged commit fd2b831 into elixir-image:main Jul 9, 2026
6 checks passed
@hlindset

hlindset commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

I knew that I was handling pre-multiplied badly - you fixing this area is really fabulous, thank you.

Ah, I think the pre-existing premultiply/unpremultiply in resize is fine. This one was actually my doing. A quirk in when libvips inserts the background fill (after premultiply, before unpremultiply) which ended up warping the color bands if the background had alpha.

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