How to extract part of this image in Java? [closed

2019-01-21 00:41发布

问题:

I have this sprite sheet:

Pacman sprites http://i39.tinypic.com/145nvp.png

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

回答1:

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

The getSubimage method will take the x, y, and the width and height of 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 for loop to iterate through the large image.

For example, if the sprite image is loaded using the ImageIO class (such as the read method), 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:

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.)



回答2:

If you just want to draw the sprites, Java's Graphics class has a drawImage method 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).

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

columns is 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.

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.

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

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).