1

Below is the following code that reads in RGB values using BufferedImage, and then simply writes them back out again to file. The resultant image is perfect, and looks good. No worries there.

I run a print test to print out the first 10 RBG int values. This is to test the "test.png" file, and then to test the resultant image - "new-test.png". For some reason I am getting different RBG values between the two files.

E.g. (The first 3 RGB int values)

test.png : -16704215, -16704215, -16704215

new-test.png : -16638935, -16638935, -16573142

Can anyone identify to why I am getting different RBG values that printed out for both test files?

    try
    { 
    BufferedImage imgBuf = ImageIO.read(new File("test.png"));//also testing with GIFs, JPEGs
    int w = imgBuf.getWidth();
    int h = imgBuf.getHeight();
    int[] RGBarray = imgBuf.getRGB(0,0,w,h,null,0,w);

    //Arrays to store their respective component values
    int [][] redPixels = new int [h][w]; 
    int [][] greenPixels = new int [h][w]; 
    int [][] bluePixels = new int [h][w];

    for(int i=0; i<=10; i++)
    {
       //print out the first 10 RGB int values - testing purposes
       System.out.println(RGBarray[i]);
    }

    //Separate the RGB int values into 3 array, red, green and blue ....
    int x=0;
    for(int row=0; row<h; row++)
    {
       for(int col=0; col<w; col++)
       {
          redPixels[row][col] = ((RGBarray[x]>>16)&0xff);
          greenPixels[row][col] = ((RGBarray[x]>>8)&0xff);
          bluePixels[row][col] = (RGBarray[x]&0xff);
          x++;
       }
    }

    //set pixels back using the setRBG() ...
    BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

    for(int row=0; row<h; row++) 
    {
       for(int col=0; col<w; col++)
       {
          //use bit shifting to re-form the RGB int again
          int rgb = (redPixels[row][col] & 0xff) << 16 | (greenPixels[row][col] & 0xff) << 8 | (bluePixels[row][col] & 0xff);

          bufferedImage.setRGB(col, row, rgb);
       }
    }
  }
  catch(IOException i){}; // This exception format is only temporary !
Douglas Grealis
  • 599
  • 2
  • 11
  • 25
  • 1
    How do you create the new-test.png? – malun Mar 12 '14 at 18:45
  • Please check my last edit. There a few arrays not shown how they are declared, but there in use to represent each colour component..for Red, Green, and Blue – Douglas Grealis Mar 12 '14 at 18:53
  • Are using `ImageIO.write()` after this to save your bufferedImage as new-test.png? – malun Mar 12 '14 at 18:56
  • Yes, I was also meant to add that in too. ImageIO.write(bufferedImage, "png", new File("new-test.png")); – Douglas Grealis Mar 12 '14 at 19:07
  • Are you sure you are interpreting correctly the RGB values? Look here http://stackoverflow.com/questions/10880083/get-rgb-of-a-bufferedimage – leonbloy Mar 12 '14 at 19:17
  • Pls post the full code, imageArray is not declared – leonbloy Mar 12 '14 at 19:23
  • BTW, the orig-new values are almost equal : 01 1D 29 -> 02 1C 29 and 01 1D 29 -> 03 1D 2A . But they should be exactly equal. – leonbloy Mar 12 '14 at 19:33
  • Sorry, but what do you mean by interpreting the values correctly? The arrays are declared as int [][] imageArray = new int [h][w]; int [][] redPixels = new int [h][w]; int [][] greenPixels = new int [h][w]; int [][] bluePixels = new int [h][w]; – Douglas Grealis Mar 12 '14 at 19:45
  • In fact that is how I used the getRGB() method from reference to that other question. Also that is my point that all the values are near the same values of the new image, but slight alterations. Is it something to how I am using getRBG(), or how I am writing the data back to the stream? This would be much appreciated – Douglas Grealis Mar 12 '14 at 20:42
  • There should not be very much missing for a http://stackoverflow.com/help/mcve , and if you provided this, the error could more easily be spotted. – Marco13 Mar 12 '14 at 22:11
  • I re-edited the post to help illustrate the problem. imageArray[][] was a mistake. I am simply using the RGBarray[][] row and column sizes to loop though and bit shift to extract their colour components out into arrays, and then put them back into an int 'rgb' to form set the RBG values back. If this is not helpful, please let me know. I really would like to get the root problem. Thanks – Douglas Grealis Mar 12 '14 at 23:21
  • 1
    The code doesn't compile. You probably want to replace `BufferedImage bufferedImage = new BufferedImage(RGBarray[0].length, RGBarray.length, BufferedImage.TYPE_INT_RGB);` with `BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);` and `for(int row=0; row – malun Mar 12 '14 at 23:50
  • Ah sorry, I tried to pull together what my code looks like. But I re-edited again to alter those errors. But the question still arises, are values suppose to be the exact same from when you write the image back out? – Douglas Grealis Mar 12 '14 at 23:59
  • 2
    Here is small [modification](http://pastebin.com/pMpfZcYr) of your code that also saves the image and then reads it back again. With this code I get exactly the same `int` values before and after. Do you get a different result with this code? – malun Mar 13 '14 at 00:21
  • Wow. OK, I ran your code and called the test() method, and they seemed legit. Did you change the read method to read in the new image, and see if the values were also the same? Because mine were May I ask, what was my problem? Btw, ff this was in a form of an answer. You would of got Correct Answer :) – Douglas Grealis Mar 13 '14 at 00:37

1 Answers1

2

Here is small modification of your code that also saves the image and then reads it back again. With this code I get exactly the same int values before and after.

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.junit.Test;


public class PngReadWriteTest {

@Test
public void test(){
    try
    { 
    BufferedImage imgBuf = ImageIO.read(new File("test.png"));//also testing with GIFs, JPEGs
    int w = imgBuf.getWidth();
    int h = imgBuf.getHeight();
    int[] RGBarray = imgBuf.getRGB(0,0,w,h,null,0,w);

    //Arrays to store their respective component values
    int [][] redPixels = new int [h][w]; 
    int [][] greenPixels = new int [h][w]; 
    int [][] bluePixels = new int [h][w];

    System.out.println("IMAGE FIRST READ:");
    printPixelValues(imgBuf);

    //Separate the RGB int values into 3 array, red, green and blue ....
    int x=0;
    for(int row=0; row<h; row++)
    {
       for(int col=0; col<w; col++)
       {
          redPixels[row][col] = ((RGBarray[x]>>16)&0xff);
          greenPixels[row][col] = ((RGBarray[x]>>8)&0xff);
          bluePixels[row][col] = (RGBarray[x]&0xff);
          x++;
       }
    }

    //set pixels back using the setRBG() ...
    BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

    for(int row=0; row<h; row++)
    {
       for(int col=0; col<w; col++)
       {
          //use bit shifting to re-form the RGB int again
          int rgb = (redPixels[row][col] & 0xff) << 16 | (greenPixels[row][col] & 0xff) << 8 | (bluePixels[row][col] & 0xff);

          bufferedImage.setRGB(col, row, rgb);
       }
    }

    System.out.println("IMAGE BEFORE SAVE:");
    printPixelValues(bufferedImage);

    //Save image as png
    ImageIO.write(bufferedImage, "png", new File("new-test.png"));

    BufferedImage newImage = ImageIO.read(new File("new-test.png"));//also testing with GIFs, JPEGs

    System.out.println("IMAGE AFTER SECOND READ:");
    printPixelValues(newImage);

  }
  catch(IOException i){}; // This exception format is only temporary !
}

private void printPixelValues(BufferedImage image){
    int w = image.getWidth();
    int h = image.getHeight();
    int[] RGBarray = image.getRGB(0,0,w,h,null,0,w);

    for(int i=0; i<=10; i++)
    {
        //print out the first 10 RGB int values - testing purposes
        System.out.println(RGBarray[i]);
    }
}

}

This will only work if you use PNG since it is lossless. If you use JPG you will not get the same result since it is lossy. when you save the file as a JPG it will not result in a file containing the exact same bytes as in your first image. The level of compression will affect the image. So even if the files looks just the same by eye, they will not be exactly the same.

malun
  • 1,313
  • 9
  • 7