Skip to content

Image Compressor — Kotlin source

Shrink image file sizes entirely in your browser — fixed quality or an automatic fit to a size budget, optional max-dimension resize, batch support. Nothing uploads.

This is the Kotlin implementation — the same logic the interactive tool runs, in a shareable, citable form.

// Image compressor: quality search to a size budget — Kotlin port of the
// image-compressor tool. The search is codec-agnostic: ImageIO JPEG quality
// params (or a WebP encoder) plug in where the stand-in sits.

// Stand-in for canvas -> WebP/JPEG encode: encoded size at a quality.
private val encodeSize = { q: Double -> 12_000L + (88_000 * q).toLong() } // ~100 KB at q = 1.0

// Binary-search the quality until the encoded image fits the budget
// (targetKb * 1024) — the core of the TS compressToBudget. Returns the best
// fitting quality, or -1 when nothing fits (the TS fallback then re-encodes
// once at the 0.05 floor).
fun compressToBudget(encodeSize: (Double) -> Long, targetKb: Long): Double {
    val budget = targetKb * 1024
    var lo = 0.05
    var hi = 0.95
    var best = -1.0
    while (lo <= hi) {
        val mid = (lo + hi) / 2
        if (encodeSize(mid) <= budget) {
            best = mid          // fits — try a higher quality
            lo = mid + 0.05
        } else {
            hi = mid - 0.05     // too big — step down
        }
    }
    return best
}

fun main() {
    // The live tool decodes the bitmap, draws it to a canvas, then searches.
    // 50 KB budget: a mid-range quality fits just under it.
    val q = compressToBudget(encodeSize, targetKb = 50)
    if (q < 0.0) {
        println("no quality fits — falling back to the 0.05 floor")
        kotlin.system.exitProcess(1)
    }
    println("best quality %.3f -> %d bytes".format(q, encodeSize(q)))
}

Also available in 8 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →