Class PngEncoder
- All Implemented Interfaces:
ImageEncoder
ImageEncoder: PNG, 8-bit RGBA with straight alpha, which is
Image's pixel layout unchanged, so no channel is dropped, no value is quantized, and
decoding the result yields the bytes that went in.
Pure Java, on java.util.zip. It runs with no backend started, no window and no GL
context, which is what lets a test produce a reference image and an asset tool run headless.
Images installs it, so ImageFormat.PNG is always encodable.
Deterministic: the same Image produces the same bytes, with no timestamp, no
producer string, no adaptive choice that depends on anything but the pixels. Two runs of the same
JVM are byte-identical, which is what a test comparing against a checked-in file relies on. The
compressed payload is java.util.zip's, so a file produced by one JDK is not promised to
match one produced by another; a reference file therefore belongs to a pinned toolchain, and a
test that must survive a JDK upgrade compares decoded pixels rather than bytes.
No metadata is written: no text chunks, no colour profile, no timestamp. A PNG this writes carries pixels and nothing else.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final ImageEncoderThe installed instance; pass it toImages.uninstallEncoder(limn.graphics.ImageEncoder)to override PNG. -
Method Summary
Modifier and TypeMethodDescriptionvoidencode(Image image, ImageEncodeOptions options, OutputStream out) Writesimagetooutin the requested format.name()A short, stable, lower-case identifier used in diagnostics.booleansupports(ImageEncodeOptions options) Whether this encoder will takeoptions: the whole request, not just the format, so an encoder that supports a format only over part of the quality range can decline the rest instead of silently rounding it.
-
Field Details
-
INSTANCE
The installed instance; pass it toImages.uninstallEncoder(limn.graphics.ImageEncoder)to override PNG.
-
-
Method Details
-
name
Description copied from interface:ImageEncoderA short, stable, lower-case identifier used in diagnostics. It appears in the failure raised when nothing accepts a request, which is the only way anyone finds out which encoders existed and in what order they were consulted.It carries no meaning and nothing may branch on it; the wrong edit this prevents is a comparison against a literal name somewhere on a control-flow path, which would put one encoder's identity into logic that is supposed to be encoder-neutral.
Deliberately without a default: deriving it from the implementing class produces an unreadable synthetic name for a lambda or an anonymous class, in exactly the message that exists to be readable.
- Specified by:
namein interfaceImageEncoder- Returns:
- the identifier, never null and never blank
-
supports
Description copied from interface:ImageEncoderWhether this encoder will takeoptions: the whole request, not just the format, so an encoder that supports a format only over part of the quality range can decline the rest instead of silently rounding it.Cheap and honest, and it must never throw: it runs on the caller's thread, once per installed encoder, every time anything is encoded, and one encoder that throws here makes the probe unusable for every encoder behind it.
Declaring support is the whole reason this method exists. An encoder that claims a format it cannot fully represent (alpha into a format without an alpha channel, say) must decline rather than accept and drop the channel: a caller who is refused can choose another format, whereas a caller handed a degraded file finds out when someone looks at it.
Deliberately without a default, because both possible defaults are wrong: claiming everything destroys the ordering, and claiming nothing makes an encoder that forgot to override it silently unreachable.
- Specified by:
supportsin interfaceImageEncoder
-
encode
Description copied from interface:ImageEncoderWritesimagetooutin the requested format. Called only afterImageEncoder.supports(limn.graphics.ImageEncodeOptions)returned true for the same options. Does not closeoutand does not flush it; the caller owns the stream.Orientation is not this method's business:
imageis top-down (row 0 at the top) byImage's contract and every format this writes is defined against that same order. The wrong edit this prevents is "correcting" the row order here to match a GL framebuffer's bottom-up layout; the flip belongs to whatever read those pixels back (seeReadableSurface), and a second flip here would cancel it for one path and not the other, producing an upside-down file with no other symptom.Alpha is straight, never premultiplied, likewise by
Image's contract.The same image and the same options must produce the same bytes. Determinism is what makes an exported file comparable against a checked-in reference; an encoder that stamps a timestamp, a producer string or a random seed into its output breaks every such test.
- Specified by:
encodein interfaceImageEncoder- Throws:
IOException- ifoutfails
-