如何在Java中提取图像的一部分?

38
我有这个精灵表:

Pacman sprites

我该如何读取这个图像文件以提取其中的部分并用作sprite

1
这可能非常适合 http://gamedev.stackexchange.com/。 - James P.
2个回答

54
如果将精灵区域读入到BufferedImage中,则可以使用getSubimage方法获取精灵表的子图像。 getSubimage方法将取得所需子图像的xywidthheight,因此可以获取所需的精灵。由于大多数精灵似乎都是相同大小的,我认为可以通过嵌套for循环遍历大图像来检索它们。
例如,如果使用ImageIO类(如read方法)加载精灵图像,并且每个精灵的大小为10像素×10像素,其中有5行×5列的精灵,则可以通过以下方式获取精灵:
BufferedImage bigImg = ImageIO.read(new File("sheet.png"));
// The above line throws an checked IOException which must be caught.

final int width = 10;
final int height = 10;
final int rows = 5;
final int cols = 5;
BufferedImage[] sprites = new BufferedImage[rows * cols];

for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
        sprites[(i * cols) + j] = bigImg.getSubimage(
            j * width,
            i * height,
            width,
            height
        );
    }
}

当然,问题在于上面的代码只适用于所有精灵都是相同大小的情况,因此需要进行一些调整才能适用于给定的精灵表格。(因为右上角似乎与其他位置的大小不同。)

抱歉,我不小心按下了发布答案按钮。我会在答案中添加更多内容。 - coobird
1
getSubImage() 调用中,ij 索引似乎应该交换。 - guido
@guido 感谢您指出错误!代码已经修复。 - coobird
有什么想法可以移动精灵吗?可以使用面板或直接在绘图中移动吗? - James P.

13

如果你只是想绘制精灵,Java的Graphics类提供了一个drawImage方法,可以为你提取图像的特定区域。你只需要指定源图像,在Graphics对象中要绘制的精灵位置 (x, y, width, height)以及精灵所在图像的帧位置 (x, y, width, height)。

假设精灵的宽度和高度与你要在绘图区域上绘制的相同,则可以定义自己的方法来绘制精灵帧,如下所示:

void drawSpriteFrame(Image source, Graphics2D g2d, int x, int y,
                     int columns, int frame, int width, int height)
{
    int frameX = (frame % columns) * width;
    int frameY = (frame / columns) * height;
    g2d.drawImage(source, x, y, x+width, y+height,
                  frameX, frameY, frameX+width, frameY+height, this);
}

columns表示你的精灵表格中有多少列。该方法的前两行代码计算了精灵帧在表格中的x和y位置。

对于那些大图,在表格中需要特别处理。你可以使用平铺方式绘制它们(这种情况下,你将为每个大图绘制四个精灵),或者手动计算大图所需的x、y、宽度和高度,并用这些值来绘制精灵。

如果你的精灵表格是一个常规表格(所有精灵大小相同),并且像你的表格一样排列成5 x 15的模式,则可以通过以下方法调用绘制第20个帧:

Toolkit tk = Toolkit.getDefaultToolkit();    
Image pacman = tk.getImage(getURL("pacman.png"));
...
drawFrame(pacman, g2d, x, y, 15, 19, 25, 25);

在这里,x和y是您要在Graphics对象上绘制精灵的位置,15是您的精灵表中的列数,19是帧数(从0开始编号),25是每个精灵的宽度和高度(我做了近似处理)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接