Skip to content

Rendering

Qr.encode(...) returns a tight BitMatrix: one cell per module, no margin, no scaling. Turn it into something you can show or save with the extensions in io.github.yuroyami.kiteqr.render. That is a different package from Qr, so it needs its own imports. All of it is common code, with no platform, no UI framework and no rasterizer.

MultiFormatWriter and QRCodeWriter, unlike Qr.encode, return a matrix that is already scaled and already has a margin. Pass quietZone = 0 when rendering one of those, or you get two margins.

SVG (vector)

import io.github.yuroyami.kiteqr.render.toSvg

val svg: String = Qr.encode("hello").toSvg(
    moduleSize = 10,      // px per module (drives the <svg> width/height)
    quietZone = 4,        // margin in modules
    dark = "#101418",
    light = "#FFFFFF",    // or null for a transparent background
)

The whole symbol is emitted as a single <path>, one sub-path per dark module, with shape-rendering="crispEdges". It scales to any size and stays sharp. Put it in an <img>, an HTML page, or a PDF, or print it.

PNG (raster)

import io.github.yuroyami.kiteqr.render.toPng

val png: ByteArray = Qr.encode("hello").toPng(
    scale = 8,            // px per module
    quietZone = 4,
    dark = 0x101418,      // 0xRRGGBB
    light = 0xFFFFFF,
)

toPng uses KiteQR's own dependency-free PNG encoder (8-bit truecolor, stored DEFLATE). You get valid image bytes on every target, with no native code. Write them to a file, a data: URL, or a network response.

Drawing on screen

To draw onto a Compose surface, add kiteqr-compose. It gives you seam-free run merging, ImageBitmap output, and the QrCode composable. See Compose binding.