使用BufferedImage读取和写入图像文件

时间:2014-03-12 18:30:51

标签: java bufferedimage

下面是使用BufferedImage读取RGB值的以下代码,然后将它们再次写回文件。由此产生的图像是完美的,看起来很好。不用担心。

我运行打印测试以打印出前10个RBG int值。这是为了测试" test.png"文件,然后测试结果图像 - " new-test.png"。 出于某种原因,我在两个文件之间获得了不同的RBG值。

E.g。 (前3个RGB int值)

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

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

任何人都可以确定为什么我会为两个测试文件打印出不同的RBG值吗?

    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 !

1 个答案:

答案 0 :(得分:2)

以下是对代码的小修改,它还会保存图像,然后再次将其读回。使用此代码,我在前后获得完全相同的int值。

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]);
    }
}

}

这只有在你使用PNG时才有效,因为它是无损的。如果你使用JPG,你将得不到相同的结果,因为它是有损的。将文件另存为JPG时,不会生成包含与第一张图像完全相同的字节的文件。压缩级别将影响图像。因此,即使文件看起来只是相同,它们也不会完全相同。