【问题标题】:What's the purpose of the sBIT chunk in the PNG file?PNG文件中sBIT块的用途是什么?
【发布时间】:2012-03-19 05:26:17
【问题描述】:

实际上,我不明白如何在 PNG 文件中使用 sBIT 块。

我正在存储来自 11 位/通道 RGB 源的 PNG 文件,因此我尽职尽责地在我的 (c) 代码中设置了 sBIT 块:

...
png_color_8 sig_bit;

sig_bit.gray = 0;
sig_bit.alpha = 0;
sig_bit.red = 11;
sig_bit.green = 11;
sig_bit.blue = 11;

png_set_sBIT(png_ptr, info_ptr, &sig_bit);
...
/* save the png */

当使用 windows 查看器(原生 Vista 图片查看器/Paint.net)查看图像时,低 8 位被截断,所以我只能看到高 3 位。我原以为sBIT 块会自动指示读者将像素左移 5 位,以使 MSB 证明数据显示的合理性。好像不是这样的。

当我在代码中打开具有或不具有 sBIT 块的 png 文件时,请执行以下操作:

png_color_8p sig_bit;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) {
    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
    png_set_shift(png_ptr, sig_bit);
}

像素数据相同。

sBIT块的使用模型是什么?我可以以某种方式使用sBIT 块来证明像素数据的正确性以供查看,但查看“原始”数据进行数值分析吗?

【问题讨论】:

  • IHDR 块中指定的位深度是多少? sBIT is not allowed to exceed that value;如果您没有使用 16 位深度,这可能就是它无法按预期工作的原因。
  • @MichaelMadsen 16:我使用png_set_IHDR(img->p, img->i, width, height, 16, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 了解 IHDR
  • @MichaelMadsen 根据您发布的链接,我不得不怀疑:sBIT 块只是提供位掩码的一种手段吗?

标签: c png libpng


【解决方案1】:

您的源的位深度为 11,并且您正在使用它创建一个 16 位深度的 PNG 图像。所以你应该设置位,从最高有效位到最低位,为:MSBXXXX XXXX XXX0 0000LSB2,其中 11 X 来自源代码。

A decoder need not pay attention to the sBIT chunk显示创建的图像,如XXX XXXX XXXX2位深度为11和XXXX XXXX XXX0 00002 在位深度为 16 时都是相同的值。

要提取源位,您需要将位右移 (16-11sBIT)。注意:libpng 将为您完成这项工作,如果您在读取图像数据之前使用png_set_shift() 使用sBIT;或使用PNG_TRANSFORM_SHIFT 标志执行png_read_png()。好吧,回答这个问题:就是目的。

【讨论】:

    【解决方案2】:

    sBIT Chunk 告诉解码器像素数据中的有效位数。本质上,它告诉解码器数据已经左移以适应标准位深度。例如。对于 11 位数据的情况,您应该将像素左移 5 位并将它们存储为每像素 16 位。解码器将看到在每种颜色的 16 位中,只有前 11 位是重要的,因此它可以潜在地以新格式重新压缩图像,因为知道 16 位中只有 11 个有用的位。

    【讨论】:

    • 好的……那么我该如何读取数据呢? png_set_shift()好像是左移,pnglibAPI中有右移功能吗?
    • 如果你有一个格式正确的 PNG 文件,你应该能够忽略 sBIT 块并且仍然正确地显示图像,因为位已经被移动了。我写了自己的PNG编解码器,所以我对pnglib一无所知。关键是像素数据需要已经正确形成,如果解码器想知道更多细节,sBIT 块只是一个提示。
    • 在读取文件之前调用 png_set_shift() 时,libpng 会右移数据。执行此操作的函数是 png_do_unshift()(不幸的是,它所做的就是阻止我将 8 位数据转换为 4 位压缩数据)
    猜你喜欢
    • 2020-05-31
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 2019-05-19
    相关资源
    最近更新 更多