Skip to content
Image docs0.3

Basic processing workshop

Latest stable Based on Image release 0.3.0

Runnable example

This workshop turns three bundled images into five deterministic outputs without a web framework or native runtime. It demonstrates file-backed loading, bounded resizing, saliency-aware smart cropping, format conversion, a text watermark, and suspend-aware encoding.

Start here when learning bluetape4k-images, validating a workstation, or reducing a processing problem to a small JVM-only reproduction. It is also the best baseline before comparing the same workload with libvips.

This runnable example is not published. Consumers should select one bluetape4k-dependencies release-train version and then add bluetape4k-images without managing an image-module version separately.

  • suspendLoadImage(Path) reads a file-backed resource without an application-owned compressed ByteArray copy.
  • fit preserves aspect ratio; smartCropTo fills an exact target using saliency-aware cropping.
  • withGraphics adds a watermark while keeping the transformation in the immutable-image pipeline.
  • suspendWrite chooses a JPEG or PNG writer from the destination extension.

Prerequisite: JDK 21 or newer. No service or native package is required.

Terminal window
./gradlew :basic-processing:run
./gradlew :basic-processing:run --args="/tmp/bluetape4k-basic-processing"

The default directory is build/tmp/basic-processing. The run produces a 320x240 thumbnail, a 640x360 smart crop, an 800x600 PNG conversion, and two 960x540 previews.

TaskRelease implementation
Load fixturessuspendLoadImage(resourcePath(...))
Preserve aspect ratioimage.fit(width, height)
Produce an exact frameimage.smartCropTo(640, 360)
Draw a watermarkimage.withGraphics { graphics -> ... }
Encode to a pathimage.suspendWrite(writer, output)

Keep path resolution, transformation, and encoding as separate steps. Select the writer explicitly, bound dimensions before expensive work, and return metadata such as width, height, byte count, and output path so tests can assert observable results.

The workshop depends only on bluetape4k-images and Kotlin coroutines. Continue to the Spring Boot or Ktor workshops when the processing function must be exposed over HTTP; continue to the vips modules when native acceleration is justified by measured workloads.

The first command uses build/tmp/basic-processing; the first program argument overrides it. Source fixtures are included by the example build from images/src/test/resources and docs/images.

  • Example resource is missing: run from the repository Gradle project so its resource source sets are assembled.
  • A resource is not a file: URL: the release example deliberately uses path-based loading; use the library stream/byte APIs for packaged-jar resources.
  • Unexpected dimensions: distinguish aspect-preserving fit from exact-frame smartCropTo.
  • Empty or unreadable output: inspect the selected writer and destination permissions, then run the deterministic test.

The command prints every filename, final dimensions, byte count, and the normalized output directory. Treat these as the smoke-test contract rather than comparing compressed byte counts, which can vary with encoder/runtime changes.

Terminal window
./gradlew :basic-processing:test

The test invokes the same generator, asserts five non-empty files, decodes every result, and checks all expected dimensions.

  1. Run this workshop and inspect all five outputs.
  2. Read the bluetape4k-images module to understand the underlying load, transform, and writer APIs.
  3. Choose spring-boot-image-api or ktor-image-api for HTTP integration.
  4. Use the image benchmark before moving a production workload to libvips.

This example is a single-process file generator. It does not cover upload validation, storage policy, native codecs, backpressure, authentication, or public delivery URLs.

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.

Basic Processing Architecture

Release README: examples/basic-processing/README.md

Basic Processing Scenario

Release README: examples/basic-processing/README.md

Basic Processing Sequence

Release README: examples/basic-processing/README.md