如何在Java中提取此图像的一部分?[已关闭]

2022-09-01 04:26:42

我有这个精灵表:

Pacman sprites

如何读取此图像文件以提取其中的一部分以用作精灵


答案 1

如果将子画面区域读入 BufferedImage,则可以使用 getSubimage 方法获取精灵表的子画面。

该方法将采用所需子映像的 、 和 和,因此可以获得所需的子映像。由于大多数精灵的大小似乎相同,我认为大多数精灵都可以通过嵌套循环来迭代大图像。getSubimagexywidthheightfor

例如,如果使用 ImageIO 类(如 read 方法)加载子画面图像,并且每个子画面的大小为 10 x 10 像素,其中 5 行 x 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
        );
    }
}

当然,问题是,上面的代码只有在所有子画面大小都相同时才有效,因此需要执行一些调整才能适用于给定的精灵表。(由于右上角的大小似乎与其他大小不同。


答案 2

如果您只想绘制精灵,Java的Graphics类有一个drawImage方法,该方法将为您拉出图像的特定区域。您只需要指定源图像,要在图形对象上绘制子画面的位置(x,y,宽度,高度),以及子画面位于图像的哪个帧(x,y,宽度,高度)。

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

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,宽度和高度。

如果您的 sprite 工作表是常规工作表(所有子画面大小相同),并且它以 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 是要在图形对象上绘制子画面的位置,15 是 sprite 工作表中的列数,19 是帧(编号从 0 开始),25 是每个子画面的宽度和高度(我近似值)。


推荐