我正在操作一个图像呈现程序的代码,它正在从Color[]数组中生成输出图像,我的代码只是在保存之前使用额外的内容来更新它,也就是当原始图像实际上已经准备好的时候( Color[]数组中所有准备用RGB填充的像素位置都可以进行最后的保存)。
我这样做的原因是有能力插入文字描述我的渲染,而不需要另一个外部图形程序,将这样做(我想让它在一次-走!不需要其他外部应用程序的操作)。
出于这个原因,由于我无法访问原始准备好的BufferedImage (但我可以访问创建它的实际Color[] ),所以我不得不创建自己的类方法:
现在一切都很好,除了我无法摆脱的一件非常烦人的事情:与原始的无水印版本相比,我更新的图像看起来非常bleached-like/pale (几乎没有深度或阴影).
对我来说,看起来就像在image2 color[]转换之后(使用@stacker的解决方案Converting Image to Color array),有些东西出错了/不对,所以颜色变得苍白,我也不知道为什么。
下面是我的代码中有问题的主要部分:
BufferedImage sourceImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Color[] to BufferedImage
for (int k = 0; k < multiArrayList.size(); k++) {
// PREPARE...
int x = (int) multiArrayList.get(k)[0];
int y = (int) multiArrayList.get(k)[1];
int w = (int) multiArrayList.get(k)[2];
int h = (int) multiArrayList.get(k)[3];
Color[] data = (Color[]) multiArrayList.get(k)[4];
int border = BORDERS[k % BORDERS.length];
for (int by = 0; by < h; by++) {
for (int bx = 0; bx < w; bx++) {
if (bx == 0 || bx == w - 1) {
if (5 * by < h || 5 * (h - by - 1) < h) {
sourceImage.setRGB(x + bx, y + by, border);
}
} else if (by == 0 || by == h - 1) {
if (5 * bx < w || 5 * (w - bx - 1) < w) {
sourceImage.setRGB(x + bx, y + by, border);
}
}
}
}
// UPDATE...
for (int j = 0, index = 0; j < h; j++) {
for (int i = 0; i < w; i++, index++) {
sourceImage.setRGB(x + i, y + j, data[index].copy().toNonLinear().toRGB());
}
}
}
Graphics2D g2d = (Graphics2D) sourceImage.getGraphics();
// paints the textual watermark
drawString(g2d, text, centerX, centerY, sourceImage.getWidth());
// when saved to png at this point ALL IS JUST FINE
ImageIO.write(sourceImage, "png", new File(imageSavePath));
g2d.dispose();
// BufferedImage to Color array
int[] dt = ((DataBufferInt) sourceImage.getRaster().getDataBuffer()).getData();
bucketFull = new Color[dt.length];
for (int i = 0; i < dt.length; i++) {
bucketFull[i] = new Color(dt[i]);
}
// update and repaint output image - THIS OUTPUT IS ALREADY BLEACHED/PALE
d.ip(0, 0, width, height, renderThreads.length + 1);
d.iu(0, 0, width, height, bucketFull);
// reset objects
g2d = null;
sourceImage = null;
bucketFull = null;
multiArrayList = new ArrayList<>();我已经测试过(将它保存到另一个.png文件中,就在Graphics2D添加之后),在获得第二次转换之前,它看起来绝对可以,1:1到原始图像,包括。我在图片上的短信。
但是,正如我所说的,当它被送去渲染时,它会变白/苍白,这是我正在试图解决的问题。
BTW我最初想的可能是添加Graphics2D,所以我没有尝试它,但结果是一样的,那是漂白/苍白版本。
虽然我的过程和代码完全不同,但是输出映像与本主题中的BufferedImage color saturation (仍未解决)的情况基本相同。
这是我的两个例子-第一次原始,第二次更新(漂白/苍白)


发布于 2016-06-26 17:34:48
正如所怀疑的,问题是当将RGB值设置为BufferedImage时,将颜色值从线性RGB转换为伽马校正/sRGB值,但是当将值放回Color数组时,反向转换(返回到线性RGB)没有完成。
要么更改行(在双for循环中):
sourceImage.setRGB(x + i, y + j, data[index].copy().toNonLinear().toRGB());至
sourceImage.setRGB(x + i, y + j, data[index].toRGB());(不再需要copy(),因为不再使用toNonLinear()修改值)。
这样就完全避免了转换。
..。或者,您也可以将设置值的行从以下位置更改:
bucketFull[i] = new Color(dt[i]);至
bucketFull[i] = new Color(dt[i]).toLinear();可以说,这更“正确”(因为AWT将值视为sRGB颜色空间中的值,不管如何),但我相信第一个版本更快,颜色上的差异可以忽略不计。因此,我可能会先尝试第一个建议的修复,并使用它,除非您体验的颜色是关闭的。
https://stackoverflow.com/questions/38028684
复制相似问题