【问题标题】:Getting portion of Image using PixelReader/PixelWriter JavaFX使用 PixelReader/PixelWriter JavaFX 获取图像的一部分
【发布时间】:2016-07-04 13:18:50
【问题描述】:

我正在尝试使用 JavaFX 获取图像的一部分,但代码在 y = 1 时失败。

代码如下:

public static Image crop(Image src, int col, int row) {
    PixelReader r = src.getPixelReader();
    int sx = col * Grid.SIZE; // start x
    int sy = row * Grid.SIZE; // start y
    int ex = sx + Grid.SIZE;  // end x
    int ey = sy + Grid.SIZE;  // end y
    int rx = 0; // x to be written
    int ry = 0; // y to be written

    System.out.println(sx + ", " + sy + ", " + ex + ", " + ey);

    WritableImage out = new WritableImage(Grid.SIZE, Grid.SIZE);
    PixelWriter w = out.getPixelWriter();

    for(int y = sy; y < ey; y++, ry++) {
        for(int x = sx; x < ex; x++, rx++) {
            int c = r.getArgb(x, y);
            w.setArgb(rx, ry, c);
            System.out.println(rx + ", " + ry + ", " + x + ", " + y);
        }   
    }
    return out;
}

一切顺利,直到循环中的y变成1,然后出现这种情况:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: 32, 1
    at com.sun.prism.Image$BaseAccessor.getIndex(Unknown Source)
    at com.sun.prism.Image$BaseAccessor.setArgb(Unknown Source)
    at com.sun.prism.Image.setArgb(Unknown Source)
    at javafx.scene.image.WritableImage$2.setArgb(Unknown Source)

我不知道出了什么问题。我会提供任何其他信息。

【问题讨论】:

  • 您能解释一下Grid.SIZE 是什么以及col 和row 在这个方法中应该代表什么吗?通常要进行裁剪,您会期望开始 x 和 y、宽度和高度。两个参数似乎不够。
  • @James_D Grid.SIZE 等于 32。它应该代表要裁剪的图像的宽度和高度,col 和 row 是开始裁剪的列和行
  • 那你为什么要sx = col * Grid.SIZE?
  • 获取裁剪的起始位置。它应该是裁剪一个精灵表。如果col 等于1,则裁剪将从x = 32 开始。
  • 啊,好的。我不明白您所说的“开始裁剪的行和列”是什么意思。

标签: java image javafx


【解决方案1】:

由于在开始每个新行时没有将 rx 重置为 0,因此您会遇到索引越界异常。

但是,如果您想要 Grid.SIZE 的 src 的 Grid.SIZE,从 (col, row) 开始,更简单(并且可能性能更好)的方法是:

public static Image crop(Image src, int col, int row) {
    PixelReader r = src.getPixelReader();
    PixelFormat<IntBuffer> pixelFormat = PixelFormat.getIntArgbInstance() ;
    int[] pixels = new int[Grid.SIZE * Grid.SIZE];
    r.getPixels(col * Grid.SIZE, row * Grid.SIZE, Grid.SIZE, Grid.SIZE, pixelFormat,
        pixels, 0, Grid.SIZE);
    WritableImage out = new WritableImage(Grid.SIZE, Grid.SIZE);
    PixelWriter w = out.getPixelWriter();
    w.setPixels(0, 0, Grid.SIZE, Grid.SIZE, pixelFormat,
        pixels, 0, Grid.SIZE);
    return out ;
}

如果(col+1)*Grid.SIZE &gt; src.getWidth() 或(row+1)*Grid.SIZE &gt; src.getHeight() 显然这将失败,您可以在方法中检查并根据需要抛出IllegalArgumentException。

【讨论】:

  • 谢谢!这行得通,只是做了一些改动。 PixelFormat&lt;IntBuffer&gt; 应为 WritablePixelFormat&lt;IntBuffer&gt;,PixelFormat.createIntArgbInstance() 应为 PixelFormat.getIntArgbInstance()。
  • 糟糕,是的,已修复方法名称。但是您只需要PixelFormat,而不需要WritablePixelFormat。还弄清楚了为什么会出现异常。
  • 是的,我刚刚注意到了。性能好一点就好了,因为每次得到一个精灵都会运行这个方法,游戏运行在60fps!
猜你喜欢
  • 2018-10-20
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 2016-07-03
  • 2017-03-21
相关资源
最近更新 更多