Skip to content

bug(wasm): ImageEncoder.encodeToJpeg returns empty bytes — annotation export broken on web #187

Description

@tstapler

Summary

ImageEncoder.encodeToJpeg (kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/annotate/ImageEncoder.wasmJs.kt) returns ByteArray(0) on WASM. Any attempt to export an annotated image on the web target silently produces a 0-byte file.

Root cause

There is no straightforward way to encode a Compose ImageBitmap to JPEG bytes on WASM/browser without one of:

  • Skia JPEG encoder — not exposed to user code in Compose Multiplatform WASM builds.
  • Pixel iteration + Canvas 2DtoPixelMap() works on WASM, but writing O(width×height) pixels to a Uint8ClampedArray via JS interop is too slow for real images.
  • A JS JPEG encoder library — not currently on the classpath.

Proposed fix

Use bitmap.toPixelMap() + a hidden <canvas> element + canvas.toDataURL('image/jpeg', quality) + base64 decode to ByteArray. The main concern is performance — a 3000×2000 image requires 6M JS interop calls for pixel setting. Batching via Uint8Array written in a single JS call (passing pixel data as a flat array) would make this practical.

Alternatively, add a small JS JPEG encoder (e.g. jpeg-js) as a bundled dependency.

Affected files

  • kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/annotate/ImageEncoder.wasmJs.kt
  • kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/annotate/AnnotationExporter.kt

Labels

bug, platform: web, needs-design

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions