尝试将图像转换为BufferedImage

时间:2014-11-11 20:19:00

标签: java user-interface graphics exception-handling

我正在为游戏编写java代码,在创建健康栏时,我看到一个让我很困惑的异常。代码和堆栈如下:

代码:

package com.teamanubiz.pixelhero;

import java.awt.Graphics;
import java.awt.Image;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import com.teamanubiz.gameapi.gfx.Sprite;

public class GUIRenderLayer {

  public void renderStatBar(GUIPosition pos, Graphics g, int health, int maxHealth, int mana, int maxMana) {

    Sprite healthBar = null;
    try {
        healthBar = new Sprite(ImageIO.read(new File("res\\gui\\bar.png")));
    } catch (IOException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    healthBar.crop(0, 0, 128, 32);
    healthBar.scale(256, 32);
    Sprite manaBar = null;
    try {
        manaBar = new Sprite(ImageIO.read(new File("res\\gui\\bar.png")));
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    manaBar.crop(0, 32, 128, 32);
    manaBar.scale(265, 16);
    Sprite temp = null;
    try {
        temp = new Sprite(ImageIO.read(new File("res\\gui\\bar.png")));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    temp.crop(0, 64, 128, 32);
    temp.scale(256, 32);
    Sprite emptyHealth = new Sprite(temp.getCurrent());
    temp.scale(256, 16);
    Sprite emptyMana = new Sprite(temp.getCurrent());

    if (pos == GUIPosition.BOTTOM) {

      double percent_h = health / maxHealth;
      double percent_m = mana / maxMana;

      healthBar.crop(0, 0, (int) ((int) 256 * percent_h), 32);
      manaBar.crop(0, 0, (int) ((int) 256 * percent_m), 16);

      g.drawImage(emptyMana.getCurrent(), 100, 464, null);
      g.drawImage(emptyHealth.getCurrent(), 100, 432, null);
      g.drawImage(healthBar.getCurrent(), 100, 432, null);
      g.drawImage(manaBar.getCurrent(), 100, 464, null);

    }

  }

}

此类引用包含类Sprite的自定义库。它出于某种原因说我试图在 Sprite.java 的下面方法中将ToolkitImage转换为BufferedImage

public void crop(int xOffset, int yOffset, int width, int height) {

    BufferedImage temp = (BufferedImage) source;

    temp = temp.getSubimage(xOffset, yOffset, width, height);

    source = temp;

}

变量sourceImage的一个实例,它是 Sprite.java

中的字段

下面的堆栈声称我创建了ToolkitImage,尽管new ImageIcon("res\\gui\\bar.png").getImage()只返回Image。我没有在代码中将Image转换为ToolkitImage。这使得它非常混乱。

堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
    at com.teamanubiz.gameapi.gfx.Sprite.crop(Sprite.java:48)
    at com.teamanubiz.pixelhero.GUIRenderLayer.renderStatBar(GUIRenderLayer.java:55)
    at com.teamanubiz.pixelhero.GameWindow.tick(GameWindow.java:14)
    at com.teamanubiz.gameapi.Display.paint(Display.java:95)
    at javax.swing.RepaintManager$4.run(Unknown Source)
    at javax.swing.RepaintManager$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.access$1300(Unknown Source)
    at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$400(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
    at com.teamanubiz.gameapi.gfx.Sprite.crop(Sprite.java:48)
    at com.teamanubiz.pixelhero.GUIRenderLayer.renderStatBar(GUIRenderLayer.java:55)
    at com.teamanubiz.pixelhero.GameWindow.tick(GameWindow.java:14)
    at com.teamanubiz.gameapi.Display.paint(Display.java:95)
    at javax.swing.RepaintManager$4.run(Unknown Source)
    at javax.swing.RepaintManager$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.access$1300(Unknown Source)
    at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$400(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
    at com.teamanubiz.gameapi.gfx.Sprite.crop(Sprite.java:48)
    at com.teamanubiz.pixelhero.GUIRenderLayer.renderStatBar(GUIRenderLayer.java:55)
    at com.teamanubiz.pixelhero.GameWindow.tick(GameWindow.java:14)
    at com.teamanubiz.gameapi.Display.paint(Display.java:95)
    at javax.swing.RepaintManager$4.run(Unknown Source)
    at javax.swing.RepaintManager$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
    at javax.swing.RepaintManager.access$1300(Unknown Source)
    at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$400(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

2 个答案:

答案 0 :(得分:2)

不,你没有"转换"将图像转换为ToolKitImage,但这是JVM在您调用new ImageIcon("res\\gui\\bar.png").getImage()而不是BufferedImage时为您提供的内容。 ImageIcon API声明getImage()返回Image类型的对象,但未指定Image的类型。由于Image是一个接口,因此知道返回的Image对象必须有一些具体的类型。如果你需要一个BufferedImage,你可以使用它,并将此图像绘制到其中。

我自己,如果我想要一个BufferedImage,我甚至不会在这里使用ImageIcon,而是使用返回BufferedImage的ImageIO.read(...)

...所以

BufferedImage img = ImageIO.read(getClass().getResourceAsStream("res/gui/bar.png"));
Sprite healthBar  = new Sprite(img);

答案 1 :(得分:2)

BufferedImage是一种Image,但Image不是BufferedImage类型,例如,您可以将BufferedImage投射到Image 1}}。

使用ImageIcon,而不是使用ImageIO.read来加载图片,而是返回BufferedImage

所以不是......

 Sprite healthBar = new Sprite((Image)new ImageIcon("res\\gui\\bar.png").getImage()); // I Never Instatiated a ToolkitImage!!!!!!!!

Nb:ImageIcon将图像的实际加载委托给Toolkit并将其包装在Icon界面中

使用像...这样的东西。

Sprite healthBar = new Sprite(ImageIO.read(new File("res\\gui\\bar.png")));