【问题标题】:SDL2 / SDL Image strange PNG behavior with RGB valuesSDL2 / SDL 图像奇怪的 PNG 行为与 RGB 值
【发布时间】:2014-09-19 03:55:49
【问题描述】:

我发现了一个我无法调试但我想解决的有趣问题,因为它对于开发我需要的小工具至关重要。

基本上所有都归结为我加载到SDL_Surface 一个加载了IMG_Load("filename.png") 的PNG。代码的骨架是

surface = IMG_Load("filename.png");

然后此工具应通过应用颜色映射(这只是一个unordered_map<u32,u32>)将这个表面逐个像素地复制到另一个表面。这基本上是可行的,但是许多像素的 RGB 值略有变化,因此这种替换失败了。

例如,当像素 255,255,255 正确存储为表面中的 0xFFFFFFFF 时,另一个像素,例如 81,60,48 变为 82,62,51。我考虑过 gamma 校正,但图像本身没有绘制,因为颜色开关是在​​两个表面之前应用的,而后者在之后被绘制到纹理上。

有什么线索吗?我没有兴趣为我的问题找到另一种解决方案,因为我需要能够使用固定地图进行精确的像素颜色切换,我只是想了解为什么会发生这种情况(因为 PNG 应该只包含确切的值,被无损)并解决它。

【问题讨论】:

  • 您的显示器是否应用了某种颜色校准?
  • @Mark Ransom:不,我在 OSX 上运行,它有默认校准。事实上,我试图通过SDL_GetWindowGammaRamp 获得默认的伽马斜坡,但这些值似乎只是线性的。我想强调一个事实,即我正在处理原始数据,显示它只是一个后期阶段。

标签: c++ png sdl sdl-image


【解决方案1】:

好的,我找到了原因并修复了它。问题在于如何通过 OS X 框架加载 PNG。根据this 线程,这与embedded calibration 有关,在加载图像时会以某种方式考虑到这一点。建议的fix 如下:

CGFloat whitePoint[3] = { 1, 1, 1 };
CGFloat blackPoint[3] = { 0, 0, 0 };
CGFloat gamma[3] = { 2.2, 2.2, 2.2 };
CGFloat matrix[9] = {
    1, 1, 1,
    1, 1, 1,
    1, 1, 1
};
CGColorSpaceRef color_space =
    CGColorSpaceCreateCalibratedRGB(
                                whitePoint, blackPoint, gamma, matrix
                                );

通过修补 ImageIO.mSDL_Image 并从源代码重建它,问题自行解决。我想知道为什么它没有包含在 SDL_Image 中(或者更确切地说,只是一个具有自定义值的版本)。

【讨论】:

    猜你喜欢
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 2021-06-09
    • 2015-08-12
    • 1970-01-01
    • 2015-02-28
    相关资源
    最近更新 更多