在Java中更改像素值

时间:2014-04-03 14:53:27

标签: java rgb bufferedimage

我有一个广泛执行以下工作测试计划:

  1. 使用BufferedImage
  2. 读入图像文件
  3. 将位移值转换为适当的数组
  4. 将值移位到整数
  5. 将值作为图像文件写回。
  6. 这很有效。

    我正在尝试更改读取和写入图像文件之间的像素值。 (在这种情况下,我试图更改红色组件中的第一个值。我使用测试打印机打印出值来查看更改。 它显示它已更改,但是当再次读取新图像时(值已更改),该值是否保持不变?

    下面是代码(它编译并运行) - 只需要取消注释该行以更改像素值,然后在读取新的更改图像时,再次注释掉该行以了解我的问题。

    import java.awt.image.BufferedImage;
    import java.io.*;
    import javax.imageio.ImageIO;
    import java.nio.*;
    import java.util.*;
    
    public class JPEGtester
    {
       public static void main(String[] args)
       {
          int[] RGBarray = null;
          int w = 0;
          int h = 0;
    
          //Declare color arrays
          int [][] alphaPixels = null;
          int [][] redPixels = null;
          int [][] greenPixels = null;
          int [][] bluePixels =null;
    
          BufferedImage imgBuf =null;
          try
          { 
             //Read image file -- (WHEN VALUE IS CHANGED, CHANGE THE IMAGE NAME TO new-test.jpg)
             imgBuf = ImageIO.read(new File("test.jpg"));
    
             //Get width and hieght of image
             w = imgBuf.getWidth();
             h = imgBuf.getHeight();
    
             RGBarray = imgBuf.getRGB(0,0,w,h,null,0,w);
    
             alphaPixels = new int [h][w];
             redPixels = new int [h][w];
             greenPixels = new int [h][w];
             bluePixels = new int [h][w];
    
             //Bit shift values into arrays
             int i=0;
             for(int row=0; row<h; row++)
             {
                for(int col=0; col<w; col++)
                {
                   alphaPixels[row][col] = ((RGBarray[i]>>24)&0xff);
                   redPixels[row][col] = ((RGBarray[i]>>16)&0xff);
                   greenPixels[row][col] = ((RGBarray[i]>>8)&0xff);
                   bluePixels[row][col] = (RGBarray[i]&0xff);
                   i++;
                }
             }
    
             //THIS IS TRYING TO CHANGE THE FIRST VALUE OF THE RED PIXEL IN THE ARRAY BY ADDING 1
             //UNCOMMENT THIS LINE TO CHANGE VALUES, AND THEN WILL PRINT OUT THE CHANGES VALUE IN THE TEST PRINTED ARRAY
             //THEN COMMENT THE LINE AND RE-RUN WITH THE NEW IMAGE. IT REMAINS UNCHANGED ?? (AS IF NEVER BEEN CHANGED)
             //redPixels[0][0] = redPixels[0][0]+1;
    
             //Test print the first 64 values of the Red Array
             for(int row=0; row<8; row++)
             {
                for(int col=0; col<8; col++)
                {
                   System.out.print(redPixels[row][col]);
                }
             }
    
             //Set the values back to integers using re-bit shifting
             for(int row=0; row<h; row++)
             {
                for(int col=0; col<w; col++)
                {
                   int rgb = (alphaPixels[row][col] & 0xff) << 24 | (redPixels[row][col] & 0xff) << 16 | (greenPixels[row][col] & 0xff) << 8 | (bluePixels[row][col] & 0xff);
                   imgBuf.setRGB(col, row, rgb);
                }
             }
    
             //Write back image
             ImageIO.write(imgBuf, "jpg", new File("new-test.jpg"));
          }
          catch(IOException i)
          {};
       }
    }
    

1 个答案:

答案 0 :(得分:0)

由于redPixels是一个单独的对象,从RGBArray复制的值是从缓冲的图像本身复制的,第一步是:

RGBArray[0] = redPixels[0][0] + 1;

imgBuf.setRGB(0,0,w,h,RGBArray,0,w);

由于有损压缩+ 1可能不足以影响不同的值。 + 10或更改相邻像素可能会有所帮助。

当然:

RGBArray[row * w + col] = ...[row][col];

或使用setRGB版本设置单个像素:

     for (int row = 0; row < h; row++)
     {
         for (int col = 0; col < w; col++)
         {
             int c = (alphaPixels[row][col] << 24)
                     | (redPixels[row][col] << 16)
                     | (greenPixels[row][col] << 8)
                     | (bluePixels[row][col]);
             imgBuf.setRGB(row, col, c);
         }
     }