[][src]Module cvr::convert

convert houses functions for converting between the sRGB and linear color spaces but also supports conversions to the HSV space and grayscale.

It's worth noting for those who are unfamiliar with the sRGB color space, it's one of the most widely used and popular color spaces.

If, for example, a user reads in a .png image file, it should be assumed that its color values are encoded as sRGB and as such, the image doesn't natively support linear math. This is because the sRGB space is encoded using a transfer function which gives it non-linear properties so even simple operations like r_1 + r_2 can have undesirable results.

Functions like srgb_to_linear aim to solve these kinds of issues while functions like linear_to_srgb enable users to convert from something they can perform linear operations on to something that they can make suitable for displaying and storing.

Read more on sRGB and its usages here.

How to Convert sRGB to Linear

use cvr::convert::iter::SRGBLinearIterator;

// `cvr` emphasizes supporting channel-major ordering of image data
// this is done for better interop with GPU-based code which would expect planar data
//
let r = [1u8, 2, 3];
let g = [4u8, 5, 6];
let b = [7u8, 8, 9];

cvr::rgb::Iter::new(&r, &g, &b)
    .srgb_to_linear()
    .enumerate()
    .for_each(|(idx, [r, g, b])| {
        // can now use the (r, g, b) values for pixel `idx`
    });

// but `cvr` also aims to help support packed pixel formats wherever it can!
//
let pixels = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
pixels
    .iter()
    .copied()
    .srgb_to_linear()
    .enumerate()
    .for_each(|(idx, [r, g, b])| {
        // can now use the (r, g, b) values for pixel `idx`
    });

While most users would expect to be operating off the 8-bit values directly, working in floating point has several attractive features. Namely, it enables your image processing to retain accuracy and it keeps values consistent across different bit depths. For example, while 0.5 always represents something half as bright as 1.0, 128 will not always be the midpoint depending on the bit-depth of the image (8-bit vs 16-bit). Other operations like white balancing are also simplified.

It's worth noting that not all 8-bit RGB values are sRGB. For example, certain cameras enable you to capture images as raw sensor values which can be interpreted linearly without loss of accuracy. Most cameras (including machine vision ones) do support sRGB though and in some cases, it is the default setting to have sRGB encoding enabled.

Modules

iter

Functions

hsv_to_linear

hsv_to_linear takes an HSV triple and converts it to its corresponding values in the linear RGB color space.

linear_to_gray

linear_to_gray takes the provided linearized RGB pixel value and converts it to its corresponding luminance in the XYZ color space.

linear_to_hsv

linear_to_hsv takes the provided linearized RGB pixel values and converts them to their representation in the HSV color space using the equation provided here.

linear_to_srgb

linear_to_srgb takes a f32 linear sRGB pixel value in the range [0, 1] and encodes it as an 8-bit value in the gamma-corrected sRGB space.

srgb_to_linear

srgb_to_linear converts an sRGB gamma-corrected 8-bit pixel value into its corresponding value in the linear sRGB color space as a f32 mapped to the range [0, 1].