使用BufferedImage读取和写入图像

时间:2014-03-11 16:26:27

标签: java rgb pixel bufferedimage

示例代码如下。代码完美无缺,可以准确地创建图像。但是创建的图像(当读回并拍摄像素时),像素似乎是1或2个值。 我正在通过在读入像素时打印像素并在将像素保存回文件之前进行简单测试。然后我在新图像上运行另一个测试仪,打印的像素就像我说的1或2个值一样(以像素为单位,例如' 24'到' 25')。 但大多数像素都是准确的,只有少数不是。这与图像的写回方式有关吗?

try
{
    //Read in image 
    BufferedImage  imgBuf = ImageIO.read(new File("image.jpg"));

    //take in pixels etc., and simply do nothing with them - testing puposes

    //Write back the image
    BufferedImage bufferedImage = new BufferedImage(imagePixelArray[0].length, imagePixelArray.length, BufferedImage.TYPE_INT_RGB);

    ImageIO.write(bufferedImage, "jpeg", new File("new-image.jpg"));
}
catch(IOException i){};

修改

下面是像素如何分割成数组,然后使用位移重新分配回数组的代码。再次,不要担心程序的逻辑。我需要确保在回读新创建的图像时这些像素(表示为redPixels,greenPixels和bluePixels)是相同的。下面的代码使用BufferedImage上面的代码。我确实使用过GIF文件。但我知道有一些正确的JPEG编码(而不是压缩数据)

    int i=0;
      //Loop through RGBarray[] assigning their respecctive colour components using bit shifting
      //jpegPixels[255][255][3] - the third part of the array is their colour comonents
      //0 - red
      //1 - green
      //2 - blue
      for(int row=0; row<h; row++)
      {
         for(int col=0; col<w; col++)
         {
            jpegPixels[row][col][0] = ((RGBarray[i]>>16)&0xff);
            jpegPixels[row][col][1] = ((RGBarray[i]>>8)&0xff);
            jpegPixels[row][col][2] = (RGBarray[i]&0xff);
            i++;
         }
      }

//3 arrays - redPixels, greenPixels and bluePixels are assigned from jpegPixels[][][]

//loop again returning back the pixel information using bit shifting
for(int row=0; row<reconstructedJPEG.length; row++)
      {
         for(int col=0; col<reconstructedJPEG[0].length; col++)
         {
            int rgb = (redPixels[row][col] & 0xff) << 16 | (greenPixels[row][col] & 0xff) << 8 | (bluePixels[row][col] & 0xff);

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

1 个答案:

答案 0 :(得分:4)

JPG使用有损压缩,因此对于这种类型的文件格式,像素永远不会精确。如果您查看已多次复制的JPG文件,您将开始看到错误的累积,通常是在图像的边界和边缘。如果要完美存储像素,请使用不使用压缩或无损压缩的其他图像文件格式类型,例如PNG。


顺便说一句,这样的代码:

catch(IOException i){};

永远不应该存在,即使只是“只是一个示例代码来说明......”。


修改
你说:

  

不,我根本没有对像素进行任何压缩。出于测试目的,我只是读取像素,然后将它们写回来反对使用BufferedImage。同样,像素值本身会略微改变1或2个值。我不知道。从测试和测试来看,现在似乎将值写回文件?

你正在使用JPG - 所以再次压缩你是否知道它。

再次,您是否尝试过使用PNG格式的图像进行实验?


编辑2
你说:

  

但这并不能解释为什么只有一些像素没有变化,但有些像素正在改变。

更改量和可能更改的像素数将取决于ImageWriter使用的压缩级别(质量级别的倒数)。如果您提取出用于jpg图像的实际ImageWriter,则可以设置此项。例如,查看this question