Использование BufferedImage для чтения и записи в файл изображения

1

Ниже приведен следующий код, который считывает значения RGB с использованием BufferedImage, а затем просто записывает их обратно в файл. Полученное изображение идеально подходит и выглядит хорошо. Не стоит беспокоиться.

Я запускаю тест печати, чтобы распечатать первые 10 значений RBG int. Это нужно проверить файл test.png, а затем проверить результирующее изображение - "new-test.png". По какой-то причине я получаю разные значения RBG между этими двумя файлами.

Например (первые 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 !
Теги:
bufferedimage

1 ответ

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, он не приведет к файлу, содержащему те же байты, что и в вашем первом изображении. Уровень сжатия повлияет на изображение. Поэтому, даже если файлы выглядят одинаково глазом, они не будут точно такими же.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню