【问题标题】:Changing pixel value in Java在 Java 中更改像素值
【发布时间】:2014-04-03 14:53:27
【问题描述】:

我有一个工作测试程序,它广泛执行以下操作:

  1. 使用BufferedImage读入图像文件
  2. 将值移位到适当的数组中
  3. 将值重新位移为整数
  4. 将值写回为图像文件。

这很好用。

我正在尝试在读取和写入图像文件之间更改像素值。 (在这种情况下,我正在尝试更改红色组件中的第一个值。我正在使用测试打印机打印出这些值以查看更改。 说明它变了,但是再次读取新图像时(值变了),值没有变化?

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

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

【问题讨论】:

  • 您知道 JPG 是有损的,因此单个稍微亮一点的像素可能会产生与未更改版本相同的压缩值,不是吗?您是否尝试过更实质性的更改?
  • 是的,我知道压缩。事实上,我确实通过向像素值添加 50 来更改值,并且整个数组集完全改变了?我不确定为什么会发生这种情况,当值加 1 时它不会改变,但是当加 50 时,会改变所有值(似乎)?
  • 你试过用 png、bmp 或其他无损格式写出来吗?
  • 好吧,JPG 压缩不会压缩单个像素,而是压缩更大的块,因此如果您大幅更改一个像素,可能会影响同一块中的所有其他像素。也许您想为您的测试使用非压缩或无损压缩格式来消除混乱的根源。
  • 我刚刚使用.gif格式再次运行程序,但值仍然没有变化?这一定与我如何写出这些值有关?或者我的位移不正确? (尽管获得了准确的图像)

标签: java rgb bufferedimage


【解决方案1】:

由于 redPixels 是一个单独的对象,其值从 RGBArray 复制而来,而 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);
         }
     }

【讨论】:

  • 感谢您的回复。但是在移入数组后我没有使用 RGBArray 数组。我只是使用那些红色、绿色和蓝色数组来写回图像。我怎样才能对我的程序使用这种更改?谢谢
  • 立即使用扩展了答案。如果您有兴趣提高效率,您可以考虑 WritableRaster 和 cs.tut.fi/lintula/manual/java/tutorial/2d/images/filtering.htmlColorConvertOp
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
相关资源
最近更新 更多