API Reference and Developer Documentation

Chroma Subsampling

JPEG is a lossy compression algorithm, meaning that it trades quality to achieve a smaller file size. The whole point of the JPEG compression format is to reproduce photographs so as to minimize file size while keeping the visual qualities as accurate to the original as possible.

Chroma subsampling is one technique towards achieving this goal; it is a technique by which images are encoded using a lower resolution for chroma (or colour) information than for luma (or brightness) information. This works because the human visual system possesses a lower sensitivity to colour differences than for luminance (or differences in brightness).

Most graphics programs and JPEG encoders perform 2x2 (or 4:2:0) chroma subsampling, which breaks the image into 2x2 pixel blocks and only stores the average color information for each 2x2 pixel group. When using Kraken.io's lossy JPEG compression, this is the default sampling scheme, and is fine for the vast majority of JPEGs.

However, Kraken.io API allows you to to specify other commonly used schemes for chroma subsampling.

4:2:0Kraken.io's default for lossy JPEG compression. Suitable for most images - this sampling scheme will yield the smallest possible file size.
4:2:2The two colour (chroma) components are sampled at half the sample rate of brightness (luma), thereby halving the horizontal chroma resolution.
4:4:4Each of the three colour components have the same sample rate as the luma channel, thus there is no chroma subsampling taking place. Use this scheme to disable chroma subsampling for the highest quality result, at the expense of a slightly larger file size.
{
    "sampling_scheme": "4:2:2"
}

It is worth noting that chroma subampling scheme overriding works for both our intelligent lossy optimization modes as well as custom quality API requests. It also applies to our Image Resizing and Image Type Conversion where a JPEG output is requested.

Images which are comprised of sharp red text on flat backgrounds, or tiny web images with a very small number of colours are great candidates for disabling chroma subsampling by setting the option "sampling_scheme": "4:4:4"

To specify a chroma subsampling scheme in your request, add the following property to the JSON payload, using one of the above values.

{
    "auth": {
        "api_key": "your_api_key",
        "api_secret": "your_api_secret"
    },
    "url": "https://example.com/image.png",
    "wait": true,
    "lossy": true,
    "sampling_scheme": "4:2:2",
}
<?php

require_once("Kraken.php");

$kraken = new Kraken("your_api_key", "your_api_secret");

$params = array(
    "url" => "https://example.com/image.png",
    "wait" => true,
    "lossy" => true,
    "sampling_scheme" => "4:2:2"
);

$data = $kraken->url($params);

if ($data["success"]) {
    echo "Success. Optimized image URL: " . $data["kraked_url"];
} else {
    echo "Fail. Error message: " . $data["message"];
}
var Kraken = require("kraken");

var kraken = new Kraken({
    "api_key": "your_api_key",
    "api_secret": "your_api_secret"
});

var params = {
    url: "https://example.com/image.png",
    wait: true,
    lossy: true,
    sampling_scheme: "4:2:2"
};

kraken.url(params, function(status) {
    if (status.success) {
        console.log("Success. Optimized image URL: %s", status.kraked_url);
    } else {
        console.log("Fail. Error message: %s", status.message);
    }
});
require 'rubygems'
require 'kraken-io'

kraken = Kraken::API.new(
    :api_key => 'your_api_key',
    :api_secret => 'your_api_secret'
)

params = {
    :wait => true,
    :lossy => true,
    :sampling_scheme => '4:2:2'
}

data = kraken.url('https://example.com/image.png', params)

if data.success
    puts 'Success! Optimized image URL: ' + data.kraked_url
else
    puts 'Fail. Error message: ' + data.message
end
package main

import (
    "log"
    "github.com/kraken-io/kraken-go"
)

func main() {
    kr, err := kraken.New("your_api_key", "your_api_secret")

    if err != nil {
        log.Fatal(err)
    }

    params := map[string]interface {} {
        "url": "https://example.com/image.png"
        "wait": true,
        "lossy": true,
        "sampling_scheme": "4:2:2"
    }

    data, err := kr.URL(params)

    if err != nil {
        log.Fatal(err)
    }

    if data["success"] != true {
        log.Println("Failed, error message ", data["message"])
    } else {
        log.Println("Success, Optimized image URL: ", data["kraked_url"])
    }
}
using Kraken;
using Kraken.Http;
using Kraken.Model;

var connection = Connection.Create("your_api_key", "your_api_secret");
var client = new Client(connection);
var response = client.OptimizeWait(
    new OptimizeWaitRequest(new Uri("https://example.com/image.png"))
    {
        Lossy = true,
        SamplingScheme = SamplingScheme.S444
    }
);

if (response.Result.StatusCode == HttpStatusCode.OK) {
    var url = response.Result.Body.KrakedUrl;
}
from krakenio import Client

api = Client('your_api_key', 'your_api_secret')

data = {
    'wait': True,
    'lossy': True,
    'sampling_scheme': '4:2:2',
}

result = api.url('https://example.com/image.png', data);

if result.get('success'):
    print(result.get('kraked_url'))
else:
    print(result.get('message'))