使用 libjpeg-turbo 从 YCCK / CMYK 转换为 BGRA 色彩空间

Conversion from YCCK / CMYK to BGRA color space with libjpeg-turbo

提问人:NutCracker 提问时间:6/24/2023 最后编辑:Christoph RackwitzNutCracker 更新时间:6/24/2023 访问量:76

问:

我的输入上有一个 YCCK 图像,我使用 libjpeg-turbo 首先将其转换为 CMYK,然后手动将 CMYK 转换为 BGRA。我这样做是因为我在某处读到libjpeg-turbo不支持从YCCK到BGRA的直接转换。

这是我目前的转换算法:

auto const rowStride{ jpegDecompressWrapper.cinfo().output_width * jpegDecompressWrapper.cinfo().output_components };

JSAMPARRAY buffer{ ( *( cinfo ).mem->alloc_sarray )( reinterpret_cast< j_common_ptr >( &( jpegDecompressWrapper.cinfo() ) ), JPOOL_IMAGE, rowStride, 1 ) };

while ( cinfo.output_scanline < cinfo.output_height )
{
    jpeg_read_scanlines( &cinfo, buffer, 1 );
    for ( std::size_t i{ 0U }; i < rowStride / 4; ++i )
    {
        auto const c{ static_cast< std::uint8_t >( buffer[ 0 ][ i * 4U      ] ) };
        auto const m{ static_cast< std::uint8_t >( buffer[ 0 ][ i * 4U + 1U ] ) };
        auto const y{ static_cast< std::uint8_t >( buffer[ 0 ][ i * 4U + 2U ] ) };
        auto const k{ static_cast< std::uint8_t >( buffer[ 0 ][ i * 4U + 3U ] ) };

        // Convert CMYK to RGB
        auto const r{ static_cast< std::uint8_t >( ( ( 255 - c ) * ( 255 - k ) ) / 255 ) };
        auto const g{ static_cast< std::uint8_t >( ( ( 255 - m ) * ( 255 - k ) ) / 255 ) };
        auto const b{ static_cast< std::uint8_t >( ( ( 255 - y ) * ( 255 - k ) ) / 255 ) };

        // Assign RGB values to the same pixel
        pOutput[ i * 4U      ] = b;
        pOutput[ i * 4U + 1U ] = g;
        pOutput[ i * 4U + 2U ] = r;
        pOutput[ i * 4U + 3U ] = 255;
    }

    pOutput += rowStride;
}

它很差,因为我在输出上得到的图像太暗了。

有谁知道如何改进我的算法,或者是否可以使用 libjpeg-turbo 直接将 YCCK 转换为 BGRA?

C++ 图像处理 色彩空间 libjpeg-turbo

评论

1赞 Dai 6/24/2023
在色彩空间之间进行转换并非易事:您还需要考虑伽玛校正和不同类型的RGB色彩空间(例如sRGB、Adobe RGB和线性RGB)等因素。顺便说一句,您应该删除 to,因为这意味着您将失去精度:您可能应该使用来表示中间值。static_castuint8_tdouble
0赞 Dai 6/24/2023
Смотритетакже: stackoverflow.com/questions/10566668/...
0赞 NutCracker 6/24/2023
是的,我知道这并非易事。你知道 libjpeg 是否支持这种转换吗?
1赞 NutCracker 6/24/2023
在分配每个组件时最终将需要 s,所以我不认为这是上面代码中的错误static_cast
1赞 Dai 6/24/2023
您的算术运算(如)将在积分类型上进行,在获得最终值之前,这些类型会截断值并失去精度。至少先尝试一下以消除它。( ( 255 - c ) * ( 255 - k ) ) / 255

答: 暂无答案