Unify the opacity vocabulary + fix alpha scaling for 16-bit and scRGB images - #231
Open
hlindset wants to merge 1 commit into
Open
Unify the opacity vocabulary + fix alpha scaling for 16-bit and scRGB images#231hlindset wants to merge 1 commit into
hlindset wants to merge 1 commit into
Conversation
hlindset
force-pushed
the
fix/opacity-naming-and-alpha-scaling
branch
from
August 11, 2026 10:32
9684609 to
67f0fe8
Compare
hlindset
force-pushed
the
fix/opacity-naming-and-alpha-scaling
branch
from
August 11, 2026 10:34
67f0fe8 to
120b2cc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This work unifies the naming for setting and operating on opacities. Previously transparency, alpha and opacity were all used. The naming is now split in two:
opacityis the value the caller sets, unscaled and independent of the image's interpretation, e.g.Image.add_alpha(image, opacity),background: {:red, opacity: 0.5}.alphais kept for operations and values that touch the alpha band directly. On the way there, I also fixed three bugs, and tightened the error contract ofImage.Pixel.All functions that take an opacity now accept the
t:Image.Pixel.opacity/0type: 8-bit notation0..255, float notation0.0..1.0,:transparent, and:opaque.Bugs fixed
Image.add_alpha/2now correctly scales the alpha band it adds to the image's interpretation. Previously wrote an 8-bit band into float and 16-bit alpha bands. Interpretations with 8-bit alpha bands are unaffected, including Lab and LCH.Image.Pixel.to_pixel/3no longer quantizes a float:opacityto a byte before scaling it. Changes alpha values for 16-bit and scRGB images given a float opacity that is not representable in the 8-bit range.Image.Pixel.to_pixel/3now applies the:opacityoption to a color given as a list of numbers.Added
Image.Pixel.put_alpha/3,Image.Pixel.put_alpha!/3: Returns a pixel with its alpha component set to a given opacity, scaled to the image's alpha band. Returns an unchanged pixel when no alpha band is present.Image.Pixel.alpha_for/2,Image.Pixel.alpha_for!/2: Scales an opacity to the alpha band of a given image, whose range depends on the interpretation.Image.Pixel.opacity_fraction/1,Image.Pixel.opacity_fraction!/1: Takest:Image.Pixel.opacity/0and returns a fraction of full opacity.Changed
:opacityoptions ofImage.Shapeand the:background_fill_opacity/:background_stroke_opacityoptions ofImage.Text.text/2accept anyt:Image.Pixel.opacity/0rather than only a float.:opacityoption ofImage.drop_shadow/2accepts anyt:Image.Pixel.opacity/0rather than any number in0.0..1.0.opacity: 1previously meant fully opaque and is now 8-bit notation for1/255, as it is everywhere else. Use1.0instead. Only1changes meaning, since0remains fully transparent.Image.Pixelreturns anImage.Erroron every error path. An unsupported interpretation was{:error, binary()}and is nowreason: :unsupported_interpretation. Invalid colors were theColorlibrary's own exceptions, and are nowreason: :invalid_colorwith the color invalueand the original text as the message. Reaches every function that resolves a color, including the:backgroundoptions.reason: :invalid_opacityinstead of:invalid_transparency.Image.add_alpha/2now accepts the fullt:Image.Pixel.opacity/0type, whereas previously it only accepted0..255,:transparent, and:opaque.Image.add_alpha/2returns{:error, %Image.Error{reason: :invalid_opacity}}for an invalid opacity, where it previously raisedFunctionClauseError.Removed
Image.Pixel.transparency/1,Image.Pixel.max_opacity/0andImage.Pixel.min_opacity/0. UseImage.Pixel.alpha_for/2for a value to write into an image's alpha band, orImage.Pixel.opacity_fraction/1for the opacity itself.t:Image.transparency/0andt:Image.Pixel.transparency/0types. Replaced byt:Image.Pixel.opacity/0.:alphaoption ofImage.Pixel.to_pixel/3and the{color, alpha: alpha}background form. Use:opacityand{color, opacity: opacity}, which are the same options under new names.:noneas an opacity, though not as a color. Use:transparent, which it was an exact synonym for.Open questions
Image.opacity/2. One possibility is to rename it to e.g.Image.multiply_alpha/2?Image.Pixel.alpha_for/2that accepts an interpretation atom, so alpha resolution can be done for an interpretation without having an image at hand. Not needed by any of the internal call sites, so I didn't add that. Easy to add, if you think it'll be useful?