首页 > 解决方案 > Freeimage FreeImage_ConvertTo24Bits 返回空指针

问题描述

我认为在以前的版本中 FreeImage_ConvertTo24Bits(FIBITMAP*) 在任何类型的 FIBITMAP* 中都可以正常工作,但在 3.18 中,如果 FIBITMAP* 是浮点纹理,它会返回 nullptr。

有什么我错过的吗?有人也注意到这个变化吗?我应该进行中间转换吗?

提前感谢您的任何提示。

标签: c++freeimage

解决方案


我没能成功,所以我编写了自己的版本,我会把它放在这里供未来的读者使用:

inline BYTE LinToSRGB(float C)
{
    C = std::fmin( std::fmax(C, 0.0f), 1.0f);
    if (C > 0.0031308f) {
        C = 1.055f * (pow(C, (1.0f / 2.4f))) - 0.055f;
    } else {
        C = 12.92f * C;
    }
    return static_cast<BYTE>(C*255.0f);
}

FIBITMAP* ConvertTo24Bits(FIBITMAP* origImage)
{
    FIBITMAP* modImage = FreeImage_ConvertTo24Bits(origImage);
    if(modImage!=nullptr)
    {
        return modImage;
    }

    const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(origImage);
    const unsigned width = FreeImage_GetWidth(origImage);
    const unsigned height = FreeImage_GetHeight(origImage);

    modImage = FreeImage_Allocate(width, height,24);

    const unsigned src_pitch = FreeImage_GetPitch(origImage);
    const unsigned dst_pitch = FreeImage_GetPitch(modImage);

    const BYTE *src_bits = (BYTE*)FreeImage_GetBits(origImage);
    BYTE *dst_bits = (BYTE*)FreeImage_GetBits(modImage);


    if(src_type == FIT_RGBAF)
    {
        for(unsigned y = 0; y < height; y++) {
            const FIRGBAF *src_pixel = (FIRGBAF*) src_bits;

            for(unsigned x = 0; x < width; x++) {
                // convert and skip alpha channel
                *dst_bits = LinToSRGB(src_pixel[x].blue);
                dst_bits++;
                *dst_bits = LinToSRGB(src_pixel[x].green);
                dst_bits++;
                *dst_bits = LinToSRGB(src_pixel[x].red);
                dst_bits++;
            }
            src_bits += src_pitch;
        }
    }
    else if(src_type == FIT_RGBF)
    {
        for(unsigned y = 0; y < height; y++) {
            const FIRGBF *src_pixel = (FIRGBF*) src_bits;
            for(unsigned x = 0; x < width; x++) {
                // convert and skip alpha channel
                *dst_bits = LinToSRGB(src_pixel[x].blue);
                dst_bits++;
                *dst_bits = LinToSRGB(src_pixel[x].green);
                dst_bits++;
                *dst_bits = LinToSRGB(src_pixel[x].red);
                dst_bits++;
            }
            src_bits += src_pitch;
        }
    }

    return modImage;
}

推荐阅读