▩ Chilkat.Formats · Rendering

Rendering & Layout
render

Module size and physical units, quiet zone and padding, rotation, colors and opacity, caption text, and size constraints with shrink-to-fit.

How layout works

Modules become pixels

A QR symbol is a grid of square modules. Chilkat draws every module as an exact integer number of pixels (the pitch), which is what makes the result crisp and reliably readable. Around the symbol comes the quiet zone (in modules), then optional padding and an optional caption band; the whole canvas can then be rotated by a quarter turn. PNG and SVG are produced from the same rectangle list, so both formats have identical geometry.

1. Pitch

moduleSize (in units) is converted to pixels with dpi and rounded to the nearest integer ≥ 1. The result is reported as measurements[0].pitch, with pitchAdjusted telling you whether rounding changed anything.

2. Canvas

symbol modules + quiet zone, times the pitch, plus padding and the caption band. Reported as canvasWidth/canvasHeight (after rotation) and, for physical units, physicalWidth/physicalHeight.

3. Constraints

maxWidth, maxHeight and limits.maxPixels are checked against the rotated canvas. A symbol that does not fit is a noFit error for generate and a fits: false report for measure.

Module size and units

Pixels or physical units

MemberValuesDefaultNotes
render.units"px" · "mm" · "in" · "pt""px"The unit of moduleSize, padding, maxWidth, maxHeight and minModuleSize.
render.moduleSize> 04 (px)Size of one module in units. Rounded to an integer pixel pitch.
render.dpi1–9600300Converts physical units to pixels. Also written into the PNG (pHYs) so image viewers and printers know the intended size.
render.requireExactPitchboolfalseWhen true, a moduleSize that does not round exactly to an integer pixel pitch is a no-fit (pitchAdjusted) instead of being rounded.
request
{ "payload": { "text": "https://www.chilkatsoft.com" },
  "render": { "units": "mm", "moduleSize": 0.5, "dpi": 300 } }
measurements[0] in the response
{ "index": 0, "fits": true, "units": "mm", "dpi": 300, "pitch": 6, "requestedPitch": 5.905512, "pitchAdjusted": true,
  "moduleSize": 0.508, "canvasWidth": 222, "canvasHeight": 222, "physicalWidth": 18.796, "physicalHeight": 18.796, ... }
Because the pitch is always a whole number of pixels, the physical size you get back (moduleSize 0.508 mm here) can differ slightly from what you asked for. Read it from measurements[] rather than assuming the request value, or set requireExactPitch if the difference is not acceptable.

Quiet zone and padding

Space around the symbol

The quiet zone is the blank margin readers need; the QR standard requires 4 modules on each side, which is the default. Padding is additional space outside the quiet zone, measured in units.

MemberValuesDefaultNotes
render.quietZone"standard" or { "left", "top", "right", "bottom" } in modules (each 4–100)"standard" (4)Values below the standard 4 are rejected with outOfRange: a smaller quiet zone makes symbols unreadable.
render.padding≥ 0, in units0Extra margin outside the quiet zone, e.g. to leave room for a border or to center the symbol in a fixed box.
request
{ "payload": { "text": "https://www.chilkatsoft.com" },
  "render": { "moduleSize": 5, "quietZone": { "left": 10, "top": 10, "right": 10, "bottom": 10 }, "padding": 8 } }

Rotation

Quarter turns

render.rotation accepts 0, 90, 180 or 270 (degrees, clockwise). The entire canvas rotates — quiet zone, padding and caption included — and canvasWidth/canvasHeight describe the rotated result. Other angles are rejected (invalidEnum).

request
{ "payload": { "text": "ORDER-12345" },
  "render": { "moduleSize": 5, "rotation": 90, "text": { "enabled": true, "value": "ORDER-12345" } } }

Colors

Foreground, background and opacity

A paint is either a "#RRGGBB" string or an object { "color": "#RRGGBB", "opacity": 0..1 }. The foreground paints the dark modules (and the caption); the background fills the whole canvas.

MemberValuesDefaultNotes
render.foregroundpaint"#000000"Keep it dark on a light background: readers need contrast, and most do not decode inverted symbols.
render.backgroundpaint"#ffffff"Opacity 0 gives a transparent background (PNG becomes RGBA; SVG omits the background rect).

The PNG pixel format follows the paints: 8-bit grayscale when both paints are neutral (gray) and opaque, RGB when the background is opaque, RGBA when it is not. Translucent paints are composited with ordinary source-over alpha; SVG carries the same colors as fill and fill-opacity, so both formats look the same.

request
{ "payload": { "text": "https://www.chilkatsoft.com" },
  "render": { "moduleSize": 6, "foreground": "#083e7d", "background": { "color": "#ffffff", "opacity": 0 } } }

Caption text

Human-readable text under or over the symbol

A caption is drawn with a built-in 5×7 pixel font — no system fonts are used, so PNG and SVG captions are identical on every platform and the SVG needs no text elements. Each glyph cell is scaled by an integer factor.

MemberValuesDefaultNotes
render.text.enabledboolfalseTurns the caption on.
render.text.valueprintable ASCII, up to 256 bytes—The text to draw. QR has no built-in human-readable text, so an empty value draws nothing. Non-ASCII characters are rejected (outOfRange).
render.text.position"below" · "above""below"
render.text.scale1–64max(1, pitch / 2)Integer scale of the 5×7 glyph cell. The band height is 7 × scale + gap pixels.
render.text.gap0–1024 px0Space between the quiet zone and the caption.
render.text.alignment"center" · "left" · "right""center"Relative to the symbol body. A caption wider than the symbol widens the canvas.
request
{ "payload": { "text": "ORDER-12345" },
  "render": { "moduleSize": 6,
              "text": { "enabled": true, "value": "SCAN TO TRACK", "position": "above", "scale": 2, "gap": 6, "alignment": "left" } } }

The caption band is reported as measurements[0].textBandPx, with the text and scale used in measurements[0].text / textScale.


Size constraints

maxWidth, maxHeight and shrink-to-fit

Give the maximum canvas size the symbol may occupy. By default ("sizing": "fixed") a symbol that exceeds it is a no-fit. With "sizing": "shrinkToFit" the pitch is reduced, one pixel at a time, until the canvas fits — but never below minModuleSize.

MemberValuesDefaultNotes
render.maxWidth
render.maxHeight
> 0, in unitsnoneApplied to the rotated canvas including quiet zone, padding and caption.
render.sizing"fixed" · "shrinkToFit""fixed"shrinkToFit requires minModuleSize.
render.minModuleSize> 0, in units—The smallest module the shrink may reach. Only valid with shrinkToFit, and must not exceed moduleSize.
request
{ "payload": { "text": "https://www.chilkatsoft.com" },
  "render": { "moduleSize": 10, "maxWidth": 200, "sizing": "shrinkToFit", "minModuleSize": 2 } }
measurements[0] (abridged)
{ "pitch": 5, "requestedPitch": 10, "pitchAdjusted": true, "canvasWidth": 185, "canvasHeight": 185, ... }

When nothing fits

generate fails with noFit at /render and names the reason in the message; measure succeeds with fits: false and a reasons[] entry so you can decide what to change.

ReasonMeaning
exceedsMaxWidth
exceedsMaxHeight
The canvas is larger than the limit (after shrinking as far as allowed).
minModuleSizeShrinking reached minModuleSize and the canvas still does not fit.
pitchZeromoduleSize is less than half a pixel at this DPI.
pitchAdjustedrequireExactPitch is set and the module size does not round exactly.
exceedsPixelLimitThe canvas area exceeds limits.maxPixels or a side exceeds 32,768 px.
captionNotRenderableThe caption cannot be drawn within the constraints.

Reserved options

Styling that is not yet available

These render members are part of the design and are accepted only with their default values; anything else is rejected so that no symbol is ever produced in an unintended style.

MemberAccepted nowReserved for
render.qr.moduleShape"square"rounded, dot
render.qr.finderStyle"standard"rounded, dot
render.qr.logo
render.qr.finderColor
—Embedded logos and colored finder patterns (unsupportedFeature).
render.barHeight
render.barWidthAdjustment
render.bearerBars
—Linear symbologies (optionNotApplicable / unsupportedFeature for QR).