【发布时间】:2016-10-27 23:24:56
【问题描述】:
我正在处理从 Color[] 数组生成输出图像的图像渲染器的代码,我的代码只是在保存之前用其他内容更新它,即实际准备原始图像时(所有像素位置都准备好填充了该 Color[] 数组中的 RGB,准备最终保存)。
我这样做的原因是能够插入描述我的渲染的文本,而无需另一个可以执行此操作的外部图形程序(我想一次性完成所有操作!无需另一个外部应用程序) .
出于这个原因 - 因为我无法访问/访问原始准备的 BufferedImage(但我可以访问创建它的实际 Color[]),所以我必须创建自己的类方法:
- 将原来的 Color[] 转换为我自己的临时 BufferedImage
- 更新该温度。 BufferedImage 与我的东西通过 Graphics2D(添加一些文本到图像)
- 将我的结果(带有 Graphics2D 的 temp.BufferedImage)转换回 Color[]
- 将最终的 Color[] 发送回原始图像渲染方法 这实际上会使它成为渲染出来的最终图像 并保存为 png
现在一切正常,除了我无法摆脱的一件非常烦人的事情:我更新的图像看起来非常漂白/苍白(几乎没有深度或阴影)原始无水印版本...
在我看来,在 image2color[] 转换之后(使用 @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<>();
我已经测试(通过在添加 Graphics2D 后立即将其保存到另一个 .png 文件),在它进行第二次转换之前,它看起来绝对可以 1:1 到原始图像,包括。我在那张图片上的文字。
但正如我所说,当它发送渲染时,它会变白/苍白,这是我要解决的问题。
顺便说一句我一开始以为可能是添加了 Graphics2D,所以我确实尝试了没有它,但结果是一样的,那就是漂白/苍白的版本。
虽然我的流程和代码完全不同,但输出图像基本上与本主题完全相同(仍未解决)BufferedImage color saturation
这是我的 2 个示例 - 第一个原始,第二个更新(漂白/苍白)
【问题讨论】:
-
您使用的
Color类是什么?好像不是java.awt.Color...更具体地说,data[index].copy().toNonLinear().toRGB()是做什么的?似乎您在将颜色值传递给BufferedImage之前对其进行了转换。但是你不要在任何地方做相反的事情。我怀疑这是问题所在。 -
@haraldK 它使用 float 0-1 而不是 int 0-255,data[index].copy().toNonLinear().toRGB() 取自原始代码不太清楚它到底是什么确实如此,但我认为它可以纠正/操纵伽玛...无论如何:我现在在没有“.copy().toNonLinear()”部分和 WOW: NOW IT RENDERS OK 的情况下对其进行了测试 - 非常感谢!您想将此作为独立建议发布,以便我可以将其作为正确答案签名吗? ;-)
-
好!我已经添加了一个答案。 :-)
标签: java image colors rendering bufferedimage