简体   繁体   English

如何将子图像从Sprite工作表转换为数组

[英]How to get sub image from a sprite sheet into an array

I have a sprite sheet that will be 5x5 and each sprite is 20x20 pixels. 我有一个精灵表,它将是5x5,每个精灵是20x20像素。 I need to get each item of that sprite sheet into an array. 我需要将精灵表的每个项目放入一个数组中。 I made a for loop but got an error. 我做了一个for循环,但是遇到了一个错误。 So I tried defining one of the sub images in the array myself but still get an error. 因此,我尝试自己定义数组中的子图像之一,但仍然出现错误。 I do not get an error when I don't print an item of that array. 当我不打印该数组的项目时,我没有收到错误。 I now can not figure out the for loop problem. 我现在不知道for循环问题。

Here's my code so far 到目前为止,这是我的代码

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;


public class LoopSub extends Component {

    BufferedImage img;
    BufferedImage img2;
    BufferedImage bigImg;
    BufferedImage[] sprites;

    public void paint(Graphics g) {
        g.drawImage(img, 0, 0, null);
        g.drawImage(img2, 18, 0, null); //letter size 20x20 ; set lower to overlap
        g.drawImage(sprites[0], 36, 0, null); //this is whats causing the error

    }

    public LoopSub() {
       try {
           img = ImageIO.read(new File("res/a.png"));
           img2 = ImageIO.read(new File("res/b.png"));



           /////////////////////////////


        bigImg = ImageIO.read(new File("sheet.png"));


        final int width = 20;
        final int height = 20;
        final int rows = 5;
        final int cols = 5;
        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
                );
            }
        }

        sprites[0] = bigImg.getSubimage(1,1,1,1); //where I tried to define the array myself

           /////////////////////////////////////////////


       } catch (IOException e) {
       }

    }

    public Dimension getPreferredSize() { //sets size of screen
        if (img == null) {
             return new Dimension(100,100);
        } else {
           return new Dimension(img.getWidth(null), img.getHeight(null)); //sets size to one image //// change to all images
       }
    }

    public static void main(String[] args) {

        JFrame f = new JFrame("Load Image Sample");

        f.addWindowListener(new WindowAdapter(){
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });

        f.add(new LoopSub());
        f.pack();
        f.setVisible(true);
    }
}

New error message 新错误讯息

Exception in thread "main" java.awt.image.RasterFormatException: (x + width) is outside of Raster
    at sun.awt.image.ByteInterleavedRaster.createWritableChild(Unknown Source)
    at java.awt.image.BufferedImage.getSubimage(Unknown Source)
    at LoopSub.<init>(LoopSub.java:48)
    at LoopSub.main(LoopSub.java:85)

When changing j*width to 1 it works fine. 当将j*width更改为1时,它可以正常工作。 So that's the problem. 这就是问题所在。 Just don't know why. 只是不知道为什么。

You have a NullPointerException , which means that either sprites or sprites[0] is null . 您有一个NullPointerException ,这意味着spritessprites[0]null

Given that you initialize them in the constructor, it can happens only if there is an IOException occuring in the constructor, because you are catching it, so it doesn't terminate the program. 假设您在构造函数中对其进行了初始化,则只有在构造函数中发生IOException时才可能发生,因为您正在捕获它,因此它不会终止程序。

You should: 你应该:

  • Never silently ignore an exception, like you are doing here. 切勿像您在此处那样默默地忽略异常。 if you don't do anything useful, at least put a message to print the error like this: 如果您没有做任何有用的事情,请至少输入一条消息来打印如下错误:

      } catch (IOException e) { e.printStackTrace(); } 
  • Look what is the content of the exception, which contains the root of the problem. 看一下异常的内容是什么,它包含了问题的根源。 Probably the program can not find one of your files for some reason. 程序可能由于某种原因找不到您的文件之一。

Edit : for the RasterFormatException , it means that you are getting out of the limits of the image. 编辑 :对于RasterFormatException ,这意味着您超出了图像的范围。 More specifically, j * width + width is apparently larger than the width of the image. 更具体地说, j * width + width显然大于图像的宽度。

Since j is at most 4 and width is 20, then the maximum value that j * width + width can have is 100. Your original image should then be at least 100px wide (and also 100px tall). 由于j最多为4并且width为20,因此j * width + width可以具有的最大值为100。然后,原始图像应至少为100px宽(也应为100px高)。 Check that it is indeed the case. 检查是否确实如此。

You can for example print the width this way before the loop: 例如,您可以在循环之前以这种方式打印宽度:

System.out.println("bigImg width: " + bigImg.getWidth());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM