【问题标题】:Manipulating the pixels within a BufferedImage through an Array通过数组操作 BufferedImage 中的像素
【发布时间】:2013-12-16 01:02:20
【问题描述】:

我目前正在关注从头开始的 Java 游戏开发系列。我了解大多数 java 和 oop 概念,但在处理图形和硬件加速方面经验很少。

我质疑的代码行是:

 private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
 private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

BufferedImage“图像”变量始终是通过渲染方法绘制到屏幕上的变量。通常是这样的:

 public void render() {
    BufferStrategy bs = this.getBufferStrategy;
    if(bs == null) { this.createBufferStrategy(3); return; }
    Graphics g = bs.getDrawGraphics();
    g.drawImage(image, 0, 0, WIDTH, HEIGHT, null);
    g.dispose();
    bs.show();
 }

我知道像素数组包含 BufferedImage 中的每个像素,但是,似乎每次该数组填充值时,它都会直接影响“图像”变量的内容。从来没有一种方法可以将像素数组值复制到图像中。

这些变量是否真的以这种方式联系在一起?是否使用:

private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

在图像和上面代码中创建的数组之间创建一个自动链接?也许我快疯了,只是错过了一些东西,但我已经多次审查了代码,并且没有一次是在初始创建后操纵的“图像”变量。 (当然,除了被渲染到屏幕上。)数组“像素”总是被不同的值填充,导致渲染图像发生变化。

对此有一些见解会很棒。提前谢谢!

【问题讨论】:

  • 基本上,当您询问像素数组时,您可以直接访问图像数据。因此,每当您更改数组时,它都会立即更改...

标签: java image graphics render pixels


【解决方案1】:

你为什么不打电话

image.getData()

而不是

private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

image.getData() 返回 Raster 的 副本。 getRaster() 返回具有修改像素能力的 WriteableRaster。我猜,但 getRaster() 可能会返回图像 Raster 的子级,因此如果您修改数组,则它是可写的。尝试 image.getData() 看看它是否有效。如果没有,请在此处发帖,我会仔细查看。

我对此进行了进一步调查。 JDK自带的源码显示image.getRaster().getDataBuffer().getData()返回的是源数据数组。 image.getData() 确实返回了一个副本。如果图片被修改,getData()中的数据不会被修改。

您可以在返回的 Raster 上调用 getPixels:

public int[] getPixels(int x,
              int y,
              int w,
              int h,
              int[] iArray)

返回一个 int 数组,其中包含一个像素矩形的所有样本, 每个数组元素一个样本。 ArrayIndexOutOfBoundsException 可能是 如果坐标不在范围内,则抛出。然而,明确的界限 不保证检查。

【讨论】:

  • image.getData() 确实返回一个光栅。但是,它似乎不允许我将它返回的数据存储为整数数组。逐字代码处理如下: image.getRaster() // 返回图像的光栅 .getDataBuffer () // 返回缓冲区对象 .getData() // 将光栅内的数据作为数组返回 然后将其转换为 DataBufferInt确保存储在返回中的数据是如果 tye DataBufferInt - DataBuffer 的子类。因此新的私有“int[]”像素部分。
  • 在返回的栅格上调用 getPixels() 以获取一个 int[] 像素数组。在我的答案中查看我的新编辑。
  • 我不明白对您的评论所做的新修改。你能澄清一下吗?您可以通过调用 getPixels() 从 Raster 中获取一个 int[],就像我在上面发布的那样。
  • ``私有 int[] 像素 = img.getData().getPixels(0, 0, WIDTH, HEIGHT, null); `` 我给出了一个错误“方法 getPixels(int, int, int, int, int[]) 对于 Raster 类型不明确” 换句话说,我认为它想确保栅格是 DataBuffer 类型是 DataBufferInt 或 DataBufferDouble 左右。这就是我原始问题中扩展代码的原因。你跟吗?我知道我自己也很困惑。
  • 很奇怪。我会调查的。
【解决方案2】:

使用int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); 代替image.getData()image.getData() 只返回图像数据的副本,image.getRaster() 返回允许实际写入像素的原始像素数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多