【发布时间】:2014-01-29 09:49:20
【问题描述】:
我一直在尝试使用 Java 以 PNG 图像格式对一些数据(表示为字节值 0-255 的数组)进行编码。使用 JavaScript 中的 HTML canvas 元素 getImageData() 方法读取数据(类似于:http://blog.nihilogic.dk/2008/05/compression-using-canvas-and-png.html)。
但是,输出数据并不总是与输入相同。某些值似乎与输入不同。它似乎可以编码为 1 像素高的图像,并且仅对于具有多行的图像是不正确的。我认为这可能是由于对 PNG 图像进行逐行过滤造成的,但我真的不知道。
似乎每个不正确的值只有 1 或 2 个错误。
这是 Java 代码,但我想知道它是否也可能是 ImageIO api 的问题,尤其是它的 PNG 编码器?
public static File encodeInPng(byte[] data, String filename) throws java.io.IOException{
int width = (int)Math.ceil(Math.sqrt(data.length));
int height = (int)Math.ceil((double)data.length/width);
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
int x = 0, y = 0;
for (byte b : data) {
bufImg.getRaster().setPixel(x, y, new int[]{b&0xFF});
x++;
if (x == width) {
x = 0;
y ++;
}
}
File f = new File(filename);
ImageIO.write(bufImg, "png", f);
return f;
}
编辑:该问题仅出现在特定大小(大约 50 kB,或可能为 256x256px)的 PNG 文件中。
【问题讨论】:
-
嗯,我认为您真的不想标记 JavaScript。已删除。
-
y = 0;似乎是一个错误。也许你的意思是x = 0;? -
你是对的,虽然原始代码是正确的(我在发布时更改了一些 var 名称以提高可读性)。
-
你确定
width * height在这种情况下总是== data.length吗?您是否总是创建data数组以适应方形图像(2x2、3x3、..、NxN)?否则你计算width和height的代码是错误的。 -
@haraldK:图像大小宽度高度应始终> = datasize,看来OP选择了一个正方形是为了方便。除非
Math.sqrt做了一些*真的 讨厌的四舍五入平方根,否则计算似乎是正确的。然而!即使图像大小关闭,它也不会显示 OP 报告的内容。所有太小的图像尺寸都应该在最后显示一些数据丢失。
标签: java png javax.imageio