作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在写一个 PNG 解码器,我遇到了一些奇怪的事情。通过 PNG 文件格式,我成功地解码了具有颜色索引 + tRNS(alpha)和真彩色 + tRNS(alpha)的 PNG。我目前不确定为什么我无法解码具有 Alpha 类型 PNG 的真彩色 PNG。我已验证我对 IDAT block 的膨胀是正确的。这是 block 的样子:
Width: 256
Height: 256
Bit Depth: 8
Color Type: 6
Compression: 0
Filter: 0
Interlace: 0
Length: 25
Type: tEXt
Data: 53 6f 66 74 77 61 72 65 00 41 64 6f 62 65 20 49 6d 61 67 65 52 65 61 64 79
CRC: 71c9653c
Length: 20690
Type: IDAT
Data: 78 da ec 7d 09 9c 1c 57 99 df f7 7a a6 e7 3e 5a a3 fb ...
CRC: 21550259
实际数据太长,这里就不打印了。这是我的解码逻辑,如果我错了请纠正我:
因为这是颜色类型 6,所以一个像素由 RGBA channel 表示,每个 channel 有 1 个字节。这意味着我们需要一次解释 4 个字节。使用以下代码:
ByteBuffer image = BufferUtil.getDirectByteBuffer(data.length, ByteOrder.BIG_ENDIAN);
int i = 0;
while(i < data.length){
int color = ( (data[i] & 0xff) << 24) | ( (data[i+1] & 0xff) << 16) | ( (data[i+2] & 0xff) << 8) | (data[i+3] & 0xff);
image.putInt(color);
i += 4;
奇怪的是,我得到的大部分是 RRGGBBAA = 0x00000000 数据,导致图像清晰,颜色很少。
最佳答案
问题是您忽略了观察每个扫描线的过滤。
从图像提供的解压缩数据看起来像
1 ffffffff 0 0 0 ...
2 0 0 0 0 0 0 ...
..
每行中的第一个值符合使用的过滤方法[ http://www.w3.org/TR/PNG/#9Filters]
扫描线后处理看起来像
ffffffff ffffffff ffffffff ...
ffffffff ffffffff ffffffff ...
...
这里是一些处理方法 0、1 和 2 的示例代码。
private static void processScanLine(byte filterValue, byte[] scanLine, byte[] previousScanLine) {
switch(filterValue){
case 0:break;
case 1:
for (int i =4;i<scanLine.length;i++){
scanLine[i] = (byte)(scanLine[i]+scanLine[i-4]);
}
break;
case 2:
for (int i =0;i<scanLine.length;i++){
scanLine[i] = (byte)(scanLine[i]+previousScanLine[i]);
}
break;
}
}
关于java - PNG 真彩色带 Alpha 解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24566679/
我是一名优秀的程序员,十分优秀!