ImageIO.write 正在保存图像时出现失真

4

这是我的绘画方法:

BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bi.setRGB(0, 0, width, height, rgbIntArray, 0, width);
ImageIO.write(bi, "bmp", new File("C:/Users/Felipe/Desktop/img2.bmp"));

这是我如何填充rgbIntArray的方法:

rgbIntArray = new int[(rgbArray.length / 3)];
int j = 0;
for (int i = 0; i < rgbArray.length; i += 3) 
{
    rgbIntArray[j] = unsignedToBytes(rgbArray[i]) + 
    unsignedToBytes(rgbArray[i + 1]) * 256 +
    unsignedToBytes(rgbArray[i + 2]) * 65536;
    j++;
}

我测试了这些值,它们似乎是正确的。

我认为问题出在 setRGB 的最后一个参数上,它要求“扫描线跨度”,但说实话我不知道它是什么(但我在某处找到它可能是图像的宽度)。我假设其他参数是正确的。

以下是结果:

原始图像:

原始图像 http://i.minus.com/jy7iVQxtghO0l.bmp


结果:

结果 http://i.minus.com/jz86D3YkuPPhG.bmp

我稍后会对图像进行处理。我只是打开并保存同一张图像。


2
你如何填充rgbIntArray? - Sinkingpoint
你的代码块中的 rgbArray 是什么? - user1131435
2
我猜测 width 和/或 height 与原始图像不同,很可能相差1个像素。你如何初始化这两个变量? - Lone nebula
我刚刚意识到宽度乘以高度等于82075,而rgbIntArray的长度为82320(rgbIntArray中多出了245个宽度位置)。 - Felipe Carminati
为了更快地获得更好的帮助,请发布一个SSCCE - Andrew Thompson
显示剩余2条评论
1个回答

0

我不知道你是如何初始化rgbArray的,但每一行都以一个黑色像素(在图像外部)结尾。如果你通过直接从图像文件中读取字节来初始化rgbArray,那么它可能表示一个新的行。或者你没有正确地初始化rgbArray

这些黑色像素在倾斜的图像上显示为一条对角线。

你可以通过更改以下内容来跳过每行末尾的黑色像素:

bi.setRGB(0, 0, width, height, rgbIntArray, 0, width);

转换为:

bi.setRGB(0, 0, width, height, rgbIntArray, 0, width + 1);

最后一个参数width + 1的基本意思是,如果给定行在数组中从某个索引开始,则下一行将从同一数组中比该索引高width + 1的索引处开始。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接