[英]Mapping 16 bit grayscale to 8 bit in PNG
I'm trying to decode a PNG in C# with 16 bits per channel (bpc) for a grayscale image.我正在尝试在 C# 中解码一个灰度图像,每通道 16 位 (bpc) 的 PNG。 I believe I'm decoding the correct raw values however when I convert to 8bpc for returning values I'm not calculating the same values as System.Drawing
, Gimp or SixLabors.ImageSharp
.我相信我正在解码正确的原始值,但是当我转换为 8bpc 以返回值时,我没有计算与System.Drawing
、 Gimp 或SixLabors.ImageSharp
相同的值。
Given the following byte values of a single grayscale pixel:给定单个灰度像素的以下字节值:
byte b0 = data[index];
byte b1 = data[index + 1];
I've tried the following mappings:我尝试了以下映射:
byte result = b0;
byte result = (byte)(255 * (((b0 << 8) + b1)/ushort.MaxValue));
byte result = (byte)(((b0 << 8) + b1)/256.0);
But none of these approaches seem to match the values from other software predicted for the following values:但是这些方法似乎都与其他软件为以下值预测的值不匹配:
b0 b1 expected
55 186 55
67 135 67
35 241 36
I'm sure I'm misunderstanding the correct method for normalizing back to an 8 bpc value.我确定我误解了将正常化回 8 bpc 值的正确方法。
The image in question is this:有问题的图像是这样的:
Here's the official method to convert a bit depth:这是转换位深度的官方方法:
https://www.w3.org/TR/2003/REC-PNG-20031110/#13Sample-depth-rescaling https://www.w3.org/TR/2003/REC-PNG-20031110/#13Sample-depth-rescaling
output = floor((input * MAXOUTSAMPLE / MAXINSAMPLE) + 0.5)
where
MAXINSAMPLE = (2^sampledepth)-1
MAXOUTSAMPLE = (2^desired_sampledepth)-1
So if I take your last example:因此,如果我以您的最后一个示例为例:
35 << 8 | 241 == 8960 | 241 == 9201
9201 * 255 / 65535 == 2346255 / 65535 == 35
floor(35 + 0.5) == 35
Why not 36
?为什么不是36
?
There might gamma being involved . 可能涉及伽马。
Conclusion:结论:
Check first if your in-house implementation correctly follows the specifications then adjust accordingly.首先检查您的内部实施是否正确遵循规范,然后进行相应调整。
https://www.w3.org/TR/2003/REC-PNG-20031110/ https://www.w3.org/TR/2003/REC-PNG-20031110/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.