【发布时间】:2019-08-27 19:39:03
【问题描述】:
我正在尝试在 C# 中使用每通道 16 位 (bpc) 对灰度图像解码 PNG。我相信我正在解码正确的原始值,但是当我转换为 8bpc 以返回值时,我计算的值与 System.Drawing、Gimp 或 SixLabors.ImageSharp 不同。
给定单个灰度像素的以下字节值:
byte b0 = data[index];
byte b1 = data[index + 1];
我尝试了以下映射:
byte result = b0;
byte result = (byte)(255 * (((b0 << 8) + b1)/ushort.MaxValue));
byte result = (byte)(((b0 << 8) + b1)/256.0);
但这些方法似乎都没有与其他软件预测的以下值相匹配:
b0 b1 expected
55 186 55
67 135 67
35 241 36
我确定我误解了正常化回 8 bpc 值的正确方法。
有问题的图片是这样的:
【问题讨论】:
-
这是一个很好的问题,但您应该添加是否使用 Forms 或 WPF 以及如何解码 PNG,可能有一些基础设施您可以利用而不是重新发明轮子。
-
据我所见,您在乘以
255之前先除以ushort.MaxValue,这会丢弃您稍后需要的低位,因为除法将是整数。在第一个映射中首先乘以255。 -
@Aybe 这实际上只是普通的 C#,我正在尝试编写一个 PNG 解码器,只是为了看看它是如何完成的,所以我想看看轮子是如何构建的。我目前拥有的解码逻辑在这里:github.com/EliotJones/BigGustave/blob/master/src/BigGustave/…
-
@NetMage 谢谢,我也试过这种方式,它适用于大多数情况,但看起来 (55, 186) 情况仍然失败,但我在 Gimp 和 ImageSharp 中检查了这一点其中将值视为 56,因此看起来 System.Drawing 中的 GDI+ 在映射回时对值的舍入做了一些奇怪的事情。
-
您的帖子没有说明在这种情况下出了什么问题 - 您显示的是预期值,但不是您从
result获得的错误值?还是result2?