【问题标题】:Converting Pixels to a BufferedImage将像素转换为 BufferedImage
【发布时间】:2018-04-08 02:31:02
【问题描述】:

我有一个表示像素灰度强度值的二维整数数组:

0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 
0 255 0 255 0 255 0 255 0 255 

很明显,有 5 条垂直线一旦转换为图像就会变成黑色。 但是,我的最终图像有 5 条水平线。我不明白为什么我得到黑色水平线,而不是垂直线。将 pixel[i][j] 更改为 pixel[j][i] 会产生垂直线,但这不是我想要的。我想知道为什么我的图片有 5 条水平黑线,而我的像素值有 5 条垂直黑线。

这是我的代码:

public static void main(String[] args) throws IOException {
        BufferedImage image = null;
        SampleModel sm = null;
        WritableRaster writeRaster = null;
        Raster raster = null;
        int[][] pixel = new int[10][10];

        // containing only white pixels in an image
        for (int i = 0; i < 10; i++) 
            for(int j = 0; j < 10; j++) 
                pixel[i][j] = 255;
        printPixels(pixel);

        // make black vertical lines by changing intensity value
        for (int i = 0; i < 10; i++) 
            for(int j = 0; j < 10; j+=2) 
                pixel[i][j] = 0;
        printPixels(pixel);

        image = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_GRAY);
        raster = image.getData();
        sm = raster.getSampleModel();
        writeRaster = Raster.createWritableRaster(sm, new Point(0, 0));
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                 writeRaster.setSample(i, j, 0, pixel[i][j]);
            }
        }
        image.setData(writeRaster);
        writeFile(image, "modified.gif");
    }
}

【问题讨论】:

  • 不同的坐标系。
  • setSamplex/y 坐标系中
  • “将 pixel[i][j] 更改为 pixel[j][i] 会产生垂直线,但这不是我想要的。” 为什么不呢?

标签: java image pixel


【解决方案1】:

Raster(即writeRaster)的坐标系与SampleModel的坐标系不同。根据Raster的文档:

尽管光栅可能生活在飞机的任何地方,SampleModel 使 使用从(0, 0) 开始的简单坐标系。光栅 因此包含一个平移因子,允许像素位置 在Raster 的坐标系和 SampleModel。从SampleModel 坐标系到 可以通过getSampleModelTranslateXgetSampleModelTranslateY 方法。

此外,文档指出:

Raster 封装了一个 DataBuffer,用于存储样本值和一​​个 SampleModel 描述了如何在 DataBuffer.

将这两个语句放在一起,Raster 中的样本是标准坐标平面中的样本的转置,因此在 Raster 类中包含了 getSampleModelTranslateXgetSampleModelTranslateY 方法。因此,为setSample 方法提供坐标时使用了转置坐标系。解决此问题的正确方法是反转代码中的 xy 坐标。这可能看起来像一个 hack,但这是一个正确的过程,因为两个坐标系是转置的。您的代码将是:

public static void main(String[] args) throws IOException {
    BufferedImage image = null;
    SampleModel sm = null;
    WritableRaster writeRaster = null;
    Raster raster = null;
    int[][] pixel = new int[10][10];

    // containing only white pixels in an image
    for (int i = 0; i < 10; i++) 
        for(int j = 0; j < 10; j++) 
            pixel[i][j] = 255;
    printPixels(pixel);

    // make black vertical lines by changing intensity value
    for (int i = 0; i < 10; i++) 
        for(int j = 0; j < 10; j+=2) 
            pixel[i][j] = 0;
    printPixels(pixel);

    image = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_GRAY);
    raster = image.getData();
    sm = raster.getSampleModel();
    writeRaster = Raster.createWritableRaster(sm, new Point(0, 0));
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
             writeRaster.setSample(i, j, 0, pixel[j][i]); // <--- Note: Reversal of i and j
        }
    }
    image.setData(writeRaster);
    writeFile(image, "modified.gif");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    相关资源
    最近更新 更多