c# - 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. 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
.
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.
The image in question is this:
解决方案
这是转换位深度的官方方法:
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
因此,如果我以您的最后一个示例为例:
35 << 8 | 241 == 8960 | 241 == 9201
9201 * 255 / 65535 == 2346255 / 65535 == 35
floor(35 + 0.5) == 35
为什么不36
呢?
结论:
首先检查您的内部实施是否正确遵循规范,然后进行相应调整。
推荐阅读
- excel - “应用程序”对象是否有更多方法?
- sql - 使用 SQL 进行复杂分组
- angular - Angular 2:在表单标签内输入时搜索管道不起作用
- javascript - 试图将属性“onclick”添加到由 javascript 函数创建的 html“img”元素
- php - 从 url 中删除 index.php:谷歌云
- bash - 手动创建/验证 PrimeCoin 块哈希
- directx-11 - 如何使用 DirectX11(DirectX11.1 之前的版本)创建带有全套 mipmap 的 texture2d
- python - 如何使用 Python 从布尔表达式生成弹性搜索查询?
- c++ - C++ 使用命令 sfc /scannow 运行错误
- oracle - 如何从 DB2 或 Oracle 迁移到 TiDB?