下面是使用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 !
答案 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时,不会生成包含与第一张图像完全相同的字节的文件。压缩级别将影响图像。因此,即使文件看起来只是相同,它们也不会完全相同。