[英]JAVA Color[] to BufferedImage to Color[] bleached output
我正在处理从Color []数组生成输出图像的图像渲染器的代码,而我的代码只是在保存之前(即实际准备好原始图像时(所有像素位置都准备好用RGB填充))用其他内容更新它。在该Color []数组中准备好进行最终保存)。
我这样做的原因是能够插入描述我的渲染的文本,而无需另一个外部图形程序来执行此操作(我希望一次性完成所有操作,而无需另一个外部应用程序)。
由于这个原因-因为我无法访问/访问原始准备的BufferedImage(但是我可以访问创建它的实际Color []),所以我必须创建自己的类方法:
现在,除了我无法摆脱的一件非常烦人的事情之外,一切都按我预期的那样正常工作:与原始的未加水印版本相比,我更新的图像看起来非常漂白/苍白 (几乎没有深度或阴影)...
对我来说,它看起来像是在image2color []转换后(使用@stacker解决方案, 将图像转换为Color数组 )出了问题/不正确,所以颜色变浅了,我不知道为什么。
这是有问题的代码的主要部分:
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<>();
我已经测试过(通过在添加Graphics2D之后将其保存到另一个.png文件中),在它进行第二次转换之前,它与原始图像(包括1)绝对看起来是可以的1:1。 我在那张图片上的文字。
但是正如我所说,当发送渲染时,它会变白/变苍白,这是我要解决的问题。
顺便说一句,我首先以为可能是Graphics2D的添加,所以我确实尝试了不添加它,但是结果是一样的,那就是漂白/淡色版本。
尽管我的过程和代码完全不同,但是输出图像基本上与本主题中的图像完全相同(仍未解决) BufferedImage颜色饱和度
这是我的两个示例-第一个原始版本,第二个更新版本(漂白/淡色)
令人怀疑的是,问题是当将RGB值设置为BufferedImage
,将颜色值从线性RGB转换为经过伽玛校正的/ sRGB值,但是当您将这些值放回原位时,并没有完成反向转换(回到线性RGB)。进入Color
数组。
更改行(在double 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颜色空间中的值),但是我相信第一个版本速度更快,并且颜色差异可以忽略不计。 因此,我可能会首先尝试第一个建议的修复方法,并使用该方法,除非您遇到不正常的颜色。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.