Skip to content

Image Compressor — C++ 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 C++ implementation — the same logic the interactive tool runs, in a shareable, citable form.

// Image compressor: quality search to a size budget — C++17 port of the
// image-compressor tool. The stdlib has no image codec, so the encoder is a
// stand-in sized like a real one (libjpeg-turbo / libwebp plug in here);
// the binary search over quality is the portable part.

#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>

// Stand-in for canvas -> WebP/JPEG encode: encoded size at a quality.
using EncodeSize = std::function<std::uint64_t(double quality)>;

// 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).
double compressToBudget(const EncodeSize& encodeSize, std::uint64_t targetKb) {
    const std::uint64_t budget = targetKb * 1024;
    double lo = 0.05, hi = 0.95, best = -1.0;
    while (lo <= hi) {
        const double mid = (lo + hi) / 2.0;
        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;
}

int main() {
    // The live tool decodes the bitmap, draws it to a canvas, then searches.
    // Deterministic stand-in codec: size grows ~linearly with quality.
    const EncodeSize encodeSize = [](double q) -> std::uint64_t {
        return 12'000 + 88'000 * q; // ~100 KB at q = 1.0
    };

    const double q = compressToBudget(encodeSize, 50); // 50 KB budget
    if (q < 0.0) {
        std::cout << "no quality fits — falling back to the 0.05 floor\n";
        return 1;
    }
    std::cout << std::fixed << std::setprecision(3)
              << "best quality " << q << " -> " << encodeSize(q) << " bytes\n";
    return 0;
}

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 →