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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/621835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:03:00  来源:igfitidea点击:

How to extract part of this image in Java?

java2dsprite2d-games

提问by Click Upvote

I have this sprite sheet:

我有这个精灵表:

Pacman sprites

吃豆子精灵

How can I read this image file to extract part of it to be used as a sprite?

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

采纳答案by coobird

If the sprites area read into a BufferedImage, the getSubimagemethod can be used to get a subimage of the sprite sheet.

如果精灵区域读入一个BufferedImage,则getSubimage可以使用该方法获取精灵表的子图像。

The getSubimagemethod will take the x, y, and the widthand heightof the desired subimage, so the desired sprite can be obtained. Since most of the sprites seem to be the same size, I would think most of them can be retrieved by a nested forloop to iterate through the large image.

getSubimage方法将采取xy以及widthheight期望的子图像,从而能够得到所希望的子画面。由于大多数精灵似乎大小相同,我认为它们中的大多数可以通过嵌套for循环检索以遍历大图像。

For example, if the sprite image is loaded using the ImageIOclass (such as the readmethod), and each sprite is 10 pixels by 10 pixels in size, where are 5 rows by 5 columns of sprites, the sprites can be obtained by the following:

例如,如果使用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
        );
    }
}

The catch is, of course, the above code will only work if all the sprites are the same size, so there will need to be some adjustment performed in order to work for the given sprite sheet. (As the top right-hand corner seems to be different in size from the others.)

当然,要注意的是,上面的代码只有在所有精灵的大小都相同时才有效,因此需要进行一些调整才能对给定的精灵表起作用。(因为右上角似乎与其他角的大小不同。)

回答by Bill the Lizard

If you just want to draw the sprites, Java's Graphics class has a drawImagemethod that will pull a specific area of the image out for you. You just have to specify the source image, where you want to draw the sprite on your Graphics object (x, y, width, height), and in what frame of the image the sprite is located (x, y, width, height).

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

Assuming the width and the height of the sprite are the same width and height that you want to draw on the drawing area, you could define your own method to draw a sprite frame as follows

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

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);
}

columnsis how many columns there are in your sprite sheet. The first two lines of the method calculate the x any y position of the sprite frame in your sheet.

columns是您的精灵表中有多少列。该方法的前两行计算工作表中精灵帧的 x 任意 y 位置。

Those big sprites in your sheet will require special handling. You could draw them with tiles (so you'd be drawing four sprites for each of the big images in this case), or you could manually figure out what x, y, width, and height, to use for those sprites.

工作表中的那些大精灵需要特殊处理。您可以用瓷砖绘制它们(因此在这种情况下,您将为每个大图像绘制四个精灵),或者您可以手动确定用于这些精灵的 x、y、宽度和高度。

If your sprite sheet were a regular sheet (all sprites the same size) and it was arranged in a 5 x 15 pattern as yours is, you would draw the 20th frame with the following method call

如果您的精灵表是一个普通的表(所有精灵都具有相同的大小)并且它像您一样以 5 x 15 的模式排列,您将使用以下方法调用绘制第 20 帧

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

Here, x and y are the position you want to draw the sprite on your Graphics object, 15 is the number of columns in your sprite sheet, 19 is the frame (numbering starts at 0), and 25 is the width and height of each sprite (I approximated).

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