Container conversion for attachment payloads -- NOT optimization.
vis stores and replays attachment bytes VERBATIM: whatever the user dropped
is what is stored and what the provider sees. The one thing that cannot be
passed through is a container no vision wire accepts (attachments/ provider-image-media-types): a BMP is a perfectly good image and an SVG is
a perfectly good figure, and both are a hard 400 on every provider. Since an
attachment REPLAYS on every later turn, one such row kills the whole session.
So this namespace does exactly one thing: turn bytes a provider REFUSES into the same picture in a container it ACCEPTS.
.svg / gzipped .svgz) -> rendered PNGNo downscaling, no quality knob, no size heuristics -- image optimization was removed deliberately and is not hiding here. Every failure mode (undecodable payload, missing AWT/ImageIO stack, malformed markup) returns nil, never throws; the caller then SKIPS the attachment rather than shipping bytes the provider refuses.
Container conversion for attachment payloads -- NOT optimization. vis stores and replays attachment bytes VERBATIM: whatever the user dropped is what is stored and what the provider sees. The one thing that cannot be passed through is a container no vision wire accepts (`attachments/ provider-image-media-types`): a BMP is a perfectly good image and an SVG is a perfectly good figure, and both are a hard 400 on every provider. Since an attachment REPLAYS on every later turn, one such row kills the whole session. So this namespace does exactly one thing: turn bytes a provider REFUSES into the same picture in a container it ACCEPTS. * raster (BMP, or anything else ImageIO can decode) -> PNG, 1:1, lossless * vector (`.svg` / gzipped `.svgz`) -> rendered PNG No downscaling, no quality knob, no size heuristics -- image optimization was removed deliberately and is not hiding here. Every failure mode (undecodable payload, missing AWT/ImageIO stack, malformed markup) returns nil, never throws; the caller then SKIPS the attachment rather than shipping bytes the provider refuses.
Kill switch -- bind false to make conversion unavailable (what a build with no AWT/ImageIO stack looks like).
Kill switch -- bind false to make conversion unavailable (what a build with no AWT/ImageIO stack looks like).
(rasterize-svg data)(rasterize-svg data {:keys [max-dimension]})Render an SVG (.svg or gzipped .svgz) into a PNG every vision wire
accepts. Returns {:bytes :media-type :size :original-size :width :height :original-width :original-height}, or nil when the document does not parse,
AWT/ImageIO is missing (GraalVM native-image on macOS) or conversion is
disabled. Never throws.
The ASPECT RATIO is the whole game: a squashed chart is a wrong chart, and
the model cannot tell the difference. The raster size is the document's own
resolved size -- percentages resolved against the viewBox, not jsvg's raw
.size, which reports width="100%" as 100px -- and the only scaling that
ever happens is the svg-max-raster-dimension ceiling, one factor applied
to both edges.
The canvas is filled WHITE first: SVG figures routinely leave the background transparent, and a transparent PNG of black axes is what a viewer -- or a model -- sees as an empty image.
Render an SVG (`.svg` or gzipped `.svgz`) into a PNG every vision wire
accepts. Returns `{:bytes :media-type :size :original-size :width :height
:original-width :original-height}`, or nil when the document does not parse,
AWT/ImageIO is missing (GraalVM native-image on macOS) or conversion is
disabled. Never throws.
The ASPECT RATIO is the whole game: a squashed chart is a wrong chart, and
the model cannot tell the difference. The raster size is the document's own
resolved size -- percentages resolved against the `viewBox`, not jsvg's raw
`.size`, which reports `width="100%"` as 100px -- and the only scaling that
ever happens is the [[svg-max-raster-dimension]] ceiling, one factor applied
to both edges.
The canvas is filled WHITE first: SVG figures routinely leave the background
transparent, and a transparent PNG of black axes is what a viewer -- or a
model -- sees as an empty image.Hard ceiling on the rendered long edge. A vector document can declare any size at all, and a 40000px canvas is an OOM, not a picture.
Hard ceiling on the rendered long edge. A vector document can declare any size at all, and a 40000px canvas is an OOM, not a picture.
Vector containers vis RASTERIZES on the way in instead of refusing. No
provider reads SVG -- it is markup, not pixels -- but unlike a HEIC the
pixels are recoverable: the document is rendered here, so a matplotlib
savefig(format="svg") or a dropped icon still reaches the model.
Vector containers vis RASTERIZES on the way in instead of refusing. No provider reads SVG -- it is markup, not pixels -- but unlike a HEIC the pixels are recoverable: the document is rendered here, so a matplotlib `savefig(format="svg")` or a dropped icon still reaches the model.
(to-provider-safe data media-type)Re-container data into something every vision wire accepts (PNG). Payloads
whose container is already wire-safe come back UNTOUCHED, byte for byte --
this is a validity fix, never a size one. Returns the same map as
rasterize-svg, or nil when the payload can be turned into pixels by
neither ImageIO nor the SVG renderer (HEIC, AVIF) or conversion is disabled
-- the caller must then skip it.
Re-container `data` into something every vision wire accepts (PNG). Payloads whose container is already wire-safe come back UNTOUCHED, byte for byte -- this is a validity fix, never a size one. Returns the same map as [[rasterize-svg]], or nil when the payload can be turned into pixels by neither ImageIO nor the SVG renderer (HEIC, AVIF) or conversion is disabled -- the caller must then skip it.
Containers that already need NO conversion (mirrors
attachments/provider-image-media-types). Kept here so
to-provider-safe can hand these back byte-identical instead of decoding
and re-encoding a payload that was already fine.
Containers that already need NO conversion (mirrors `attachments/provider-image-media-types`). Kept here so [[to-provider-safe]] can hand these back byte-identical instead of decoding and re-encoding a payload that was already fine.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |