Immutable image processing
Latest stable Based on Image release 0.3.0
Library module
Problem
Section titled “Problem”This module is the pure-JVM image-processing foundation. It wraps Scrimage and Java2D with Kotlin factories, immutable drawing, filter and transformation DSLs, suspend-friendly I/O, batch pipelines, thumbnails, tiles, analysis, and similarity metrics.
It is the default choice when native libvips setup is unnecessary or when a service needs rich Java2D/Scrimage operations rather than a narrow high-throughput resize pipeline.
When to use it
Section titled “When to use it”Use it for loading common web images, composing filters and watermarks, generating thumbnails, bounded batch work, similarity analysis, SVG rasterization, and coroutine-facing encoders. Choose a vips backend instead when native throughput, native memory behavior, or HEIF-family codecs dominate the decision.
Coordinates
Section titled “Coordinates”Maven coordinate: io.github.bluetape4k.image:bluetape4k-images
dependencies { implementation(platform("io.github.bluetape4k:bluetape4k-dependencies:<version>")) implementation("io.github.bluetape4k.image:bluetape4k-images")}Core concepts
Section titled “Core concepts”ImmutableImageoperations return new values.withGraphicsdraws on a copy and always disposesGraphics2D.BufferedImage.useGraphicsis intentionally mutable; it disposes the graphics object but changes the receiver.- Scrimage codecs are blocking. Suspend wrappers move them to
Dispatchers.IO; they do not turn the codec into non-blocking I/O. - Resource ownership is overload-specific:
BufferedSourceandInputStreamremain caller-owned, whileSourceandSuspendedSourceoverloads buffer and close the source. - Batch work is bounded by per-image pixels, in-flight pixels, and parallelism.
Quick start
Section titled “Quick start”val image = immutableImageOf(Path.of("photo.jpg"))
val output = image.applyFilters { brightness(1.08f) gaussianBlur(radius = 2) watermark("© bluetape4k")}
output.suspendWrite( SuspendJpegWriter.Default.withCompression(85), Path.of("photo-ready.jpg"),)API by task
Section titled “API by task”- Load:
immutableImageOfandsuspendImmutableImageOfaccept bytes, streams, Okio sources, files, and paths. - Filter:
applyFilterscomposes blur, color, effect, style, border, caption, and watermark operations. - Transform: use
autoCrop,smartCropTo,clahe,perspectiveTransform, rotation, and flips. - Compare: use perceptual hashes, histogram similarity, MSE, PSNR, SSIM/MSSIM, or block descriptors.
- Batch:
processImagesreturnsImageBatchResult; select a writer inImageProcessingDsland finish withwriteImagesTo. - Generate variants: configure
ThumbnailPipelineor split/process/merge throughTileProcessor.
Recommended patterns
Section titled “Recommended patterns”Prefer ImmutableImage at application boundaries. For batch jobs, probe dimensions before full decode, keep skipFailures=false for fail-fast jobs, and enable it only with an onFailure observer. Keep output names relative: writeImagesTo rejects paths that normalize outside its output directory.
Use suspend Okio overloads for lifecycle consistency when the caller already owns that boundary, not as a latency optimization. Release benchmarks found the Path boundary faster for the measured local workloads.
Integrations
Section titled “Integrations”CAPTCHA, OCR, and Ktor modules build on this module. Spring storage is separate from the processing DSL. images-vips-api is a different binding-neutral native surface rather than a drop-in implementation of Scrimage APIs.
Configuration
Section titled “Configuration”ImageProcessingOptions defaults to available-processor parallelism, 16,777,216 pixels per image, and 33,554,432 in-flight pixels. largeJobs() raises the bounds explicitly. The default maximum tile count is 65,536.
BatikSvgRasterizer blocks external entities and DTD loading, disables external resources by default, and enforces dimensions and timeout. Keep those defaults for untrusted SVG.
Failure modes
Section titled “Failure modes”Batch failures identify VALIDATION, LOAD, TRANSFORM, or WRITE through ImageBatchException/ImageBatchResult.Failure. Decode and writer exceptions otherwise propagate from Scrimage or ImageIO. Cancellation is rethrown rather than converted into a skipped item.
Operations
Section titled “Operations”Monitor failure counts by stage and actual image dimensions, not only compressed byte size. Set pixel budgets from production traffic. Golden-image updates are opt-in; do not enable bluetape4k.images.golden.update in ordinary CI.
Testing
Section titled “Testing”The release suite covers factories and ownership, filters, properties, golden outputs, batch limits, thumbnail and tile pipelines, similarity, SVG security, and suspend writers. Run ./gradlew :bluetape4k-images:test for the pure-JVM lane.
Workshops and learning path
Section titled “Workshops and learning path”Begin with examples/basic-processing, then study ImageProcessingDsl, ThumbnailPipeline, and TileProcessor. Read the benchmark reports before choosing libvips solely for speed; the published figures are workload- and host-specific.
Limitations
Section titled “Limitations”Suspend wrappers still bridge to blocking codecs. AVIF/HEIC types in this module are incubating contracts without a pure-JVM implementation in 0.3.0. Compressed-byte limits do not replace pixel limits, and ImageIO codec availability can vary with the runtime classpath.
Release diagrams
Section titled “Release diagrams”These diagrams are loaded directly from README assets published with the 0.3.0 release and pinned to its immutable commit. They describe this manual’s released structure and runtime flows, not later Snapshot changes. Select a preview to open the SVG at the same release commit.
Processing Pipeline diagram
Section titled “Processing Pipeline diagram”Release README: images/README.md
Transform Architecture diagram
Section titled “Transform Architecture diagram”Release README: images/README.md
Image Analysis diagram
Section titled “Image Analysis diagram”Release README: images/README.md
Images Core API Classes diagram
Section titled “Images Core API Classes diagram”Release README: images/README.md
Images Filter Classes diagram
Section titled “Images Filter Classes diagram”Release README: images/README.md
Images Writer Classes diagram
Section titled “Images Writer Classes diagram”Release README: images/README.md





