How to change the image type of a BufferedImage which is loaded from file?

谁说我不能喝 提交于 2020-01-15 06:21:07

问题


I'm trying to access the pixels in a BufferedImage which is loaded from a file using ImageIO.read(filePath), but I get this error:

Exception in thread "Game" java.lang.ClassCastException: java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt
    at com.package.graphics.Texture.<init>(Texture.java:29)
    at com.package.graphics.Texture.loadTexture(Texture.java:40)
    at com.package.Game.run(Game.java:71)
    at java.lang.Thread.run(Unknown Source)

In the code, the line which the error is on, is in the constructor and looks like this:

// Get the pixel array from the BufferedImage
this.pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

As I understand this, the BufferedImage isn't of the type BufferedImage.TYPE_INT_RGB or BufferedImage.TYPE_INT_ARGB. Because I use these types in the rest of my game, I wonder if there is a way to 'convert' the loaded image from the type it was loaded as, to another.
In my case, I want to convert the image type to BufferedImage.TYPE_INT_ARGB.


回答1:


Create a new Buffered image with the type you want

BufferedImage in = ImageIO.read(img);
BufferedImage newImage = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_INT_ARGB);

Graphics2D g = newImage.createGraphics();
g.drawImage(in, 0, 0, in.getWidth(), in.getHeight(), null);
g.dispose();



回答2:


A slightly (ok, I admit, quite a bit) more verbose, but in most cases faster and more memory efficient way of doing the same, is to load the image directly into a TYPE_INT_ARGB image.

If your images are large, you'll benefit quite a bit from doing it this way, over first loading into a byte type. If your images are small, it might not be worth the extra code complexity, as you'll hardly notice the difference.

Anyway, you can do it like this:

// Create input stream
ImageInputStream input = ImageIO.createImageInputStream(file);

try {
    // Get the reader
    Iterator<ImageReader> readers = ImageIO.getImageReaders(input);

    if (!readers.hasNext()) {
        throw new IllegalArgumentException("No reader for: " + file); // Or simply return null
    }

    ImageReader reader = readers.next();

    try {
        // Set input
        reader.setInput(input);

        // Configure the param to use the destination type you want
        ImageReadParam param = reader.getDefaultReadParam();
        param.setDestinationType(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB));

        // Finally read the image, using settings from param
        BufferedImage image = reader.read(0, param);
    }
    finally {
        // Dispose reader in finally block to avoid memory leaks
        reader.dispose();
    }
}
finally {
    // Close stream in finally block to avoid resource leaks
    input.close();
}



回答3:


You're telling the JVM that image.getRaster().getDataBuffer() returns a DataBufferInt when it actually returns a DataBufferByte. That's a ClassCastException. You need to cast the return value to the correct type.

// Get the pixel array from the BufferedImage
this.pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();


来源:https://stackoverflow.com/questions/27457517/how-to-change-the-image-type-of-a-bufferedimage-which-is-loaded-from-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!