I am manipulating code of a image renderer that is making output image from Color[] array and my code simply update it with additional stuff right before saving, that is when the original image is actually prepared (all pixels positions prepared to be filled with RGBs in that Color[] array ready for final saving).
Reason why I am doing this is to have ability to insert text describing my render without need of another external graphics program that would do that (I want to have it all in one-go! action without need of another external app).
For that cause - as I have no reach/access for the original prepared BufferedImage (but I have access to actual Color[] that it is created from) I had to make my own class method that:
- convert that original Color[] to my own temporary BufferedImage
- update that temp. BufferedImage with my stuff via Graphics2D (adding some text to image)
- convert my result (temp. BufferedImage with Graphics2D) back to Color[]
- send that final Color[] back to the original image rendering method that would actually make it to be the final image that is rendered out and saved as png
Now everything works just fine as I expected except one really annoying thing that I cannot get rid off: my updated image looks very bleached-like/pale (almost no depth or shadows presented) compared to the original un-watermarked version...
To me it simply looks like after the image2color[] conversion (using @stacker's solution from here Converting Image to Color array) something goes wrong/is not right so the colors become pale and I do not have any clue why.
Here is the main part of my code that is in question:
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<>();
I have tested (by saving it to another .png file right after the Graphics2D addition) that before it gets that 2nd conversion it looks absolutely OK 1:1 to the original image incl. my text on that image.
But as I said when it is send for render it becomes bleached/pale that is a problem I am trying to solve.
BTW I first thought it might be that Graphics2D addition so I did try it without it but the result was the same, that is bleached/pale version.
Although my process and code is completely different the output image is basically suffering exactly the same way as in this topic (still not solved) BufferedImage color saturation
Here are my 2 examples - 1st ORIGINAL, 2nd UPDATED (bleached/pale)