【问题标题】:Convert an image to a 2D array and then get the image back in Java将图像转换为二维数组,然后用 Java 取回图像
【发布时间】:2015-10-07 01:09:35
【问题描述】:

我想将图像转换为 2D 像素数组,对其进行一些操作,然后将生成的 2D 数组转换回图像。但结果我总是得到一个纯黑色的图像。我无法弄清楚我哪里出错了。这是我正在做的。所有操作都需要在8位灰度图像上完成。

  • 首先我得到二维像素数组。

    public int[][] compute(File file)
    {
    try 
    {
        BufferedImage img= ImageIO.read(file);
        Raster raster=img.getData();
        int w=raster.getWidth(),h=raster.getHeight();
        int pixels[][]=new int[w][h];
        for (int x=0;x<w;x++)
        {
            for(int y=0;y<h;y++)
            {
                pixels[x][y]=raster.getSample(x,y,0);
            }
        }
    
        return pixels;
    
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return null;
    }
    
  • 然后我对像素数组做一些操作

  • 接下来我将数组转换回图像。

    public java.awt.Image getImage(int pixels[][])
    {
         int w=pixels.length;
         int h=pixels[0].length;
         BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_BYTE_GRAY);
         WritableRaster raster=(WritableRaster)image.getData();
         for(int i=0;i<w;i++)
         {
             for(int j=0;j<h;j++)
             {
                 raster.setSample(i,j,0,pixels[i][j]);
             }
         }
    
    File output=new File("check.jpg");
    try {
        ImageIO.write(image,"jpg",output);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return image;
    }
    

但是我得到了一个全黑的图像,我确信它不是全黑的。我应该怎么做才能得到正确的结果?

编辑 - 应用 efan 的解决方案后,当我将图像保存到文件时,假设 (0,0) 的像素值为 68,然后从它更改的同一文件计算像素值有时到 70 有时到 71 .. 每个像素都有小失真。但它会破坏整个图像。有什么解决办法吗?

【问题讨论】:

  • @Dan : 打错了.. 现在更正了。

标签: java image-processing


【解决方案1】:

我认为图像完全变黑的原因是SampleModel for Raster 是错误的。这是我对您的代码所做的:

private SampleModel sampleModel;

public int[][] compute(File file)
{
    ...
    sampleModel = raster.getSampleModel();
    ...
}

public java.awt.Image getImage(int pixels[][])
{
    ...
    WritableRaster raster= Raster.createWritableRaster(sampleModel, new Point(0,0));
    for(int i=0;i<w;i++)
    {
        for(int j=0;j<h;j++)
        {
            raster.setSample(i,j,0,pixels[i][j]);
        }
    }

    BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_BYTE_GRAY);
    image.setData(raster);
    ...
}

这对我来说很好。我的理解是BufferedImage.TYPE_BYTE_GRAY 并没有完全选择你需要的东西。不同的东西可能会更好,但我不知道这些类型与颜色/样本模型究竟是如何对应的。如果您知道您需要哪个示例模型,您可以直接使用它:

WritableRaster raster= Raster.createWritableRaster(new PixelInterleavedSampleModel(0, w, h, 1, 1920, new int[] {0}), new Point(0,0));

【讨论】:

  • 感谢您的回答。现在我没有得到黑色图像,但即使在创建像素数组之后调用 getImage(int [][]) 函数而不进行任何更改,我也没有取回原始图像。而且,即使在更改了许多像素后,我也得到了相同的图像。你能告诉我原因和更正吗?谢谢
  • 我不确定我是否理解正确,但您是否尝试过使用 getPixel()、setPixel() 而不是使用 getSample()、setSample()?示例仅包含有关像素的部分信息(例如,仅来自 RGB 的红色)。
  • AFAIK 用于灰度图像 R=G=B。这两种方法我都用过。假设像素值为 71。然后我将其修改为 70 并写入图像。之后,当我读回图像时,我会得到一些不同的值,例如 68、69 或 70。
  • 灰度样本中只有一个波段,所以是的,使用 getPixel、getSample 时应该没有区别(抱歉,如果这是误导)。我也尝试了几次代码,实际上我为我的特定像素得到的不是我设置的。但这仅适用于jpg。由于 jpg 是有损压缩,这是意料之中的。您是否尝试过使用不同于“jpg”的东西? png 和 bmp 对我来说都很好。
  • 谢谢.. 使用 png 图像可以完美运行。我正在使用 LSB,因此 jpg 图像的压缩使我的工作变得困难。这样就解决了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 2022-01-15
  • 2013-07-04
  • 2018-01-03
  • 2013-09-06
相关资源
最近更新 更多