使用ImageIO加载图像时,会返回BufferedImage
。我在函数BufferedImage
中使用了此java.awt.image.BufferedImage.getSubimage(int,int,int,int)
。现在......我需要打印其中一些BufferedImage
,但java.awt.Graphics.drawImage(Image,int,int,null)
函数需要Image
,而不是BufferedImage
。如何将BufferedImage
转换为Image
?
代码:
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import java.awt.Image;
import java.io.*;
import java.net.URL;
import javax.imageio.*;
import java.awt.image.*;
import java.awt.Font;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
public class engine{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI();
}
});
}
private static void GUI(){
JFrame f = new JFrame("Daealia");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setPreferredSize(new Dimension(800, 600));
f.add(new p());
f.pack();
f.setVisible(true);
}
}
class p extends JPanel{
public p(){}
public engine eng = new engine();
public BufferedImage[][] spells;
public BufferedImage image;
public void paintComponent(Graphics g){
g.setColor(new Color(82,41,0));
g.fillRect(0,0,74,254);
g.setColor(new Color(16,8,0));
g.drawRect(0,0,74,254);
try{
image = ImageIO.read(new File("spells.png"));} catch(IOException e){System.out.println("EXCEPTION THROWN!");
}
for(int k = 0; k <= 6; k++){
spells[k][1] = image.getSubimage((34*2*k)-34*2,0,34,34);
}
for(int j = 0; j <= 6; j++){
spells[j][2] = image.getSubimage((34*2*j)-34,0,34,34);
}
for(int a = 0; a <= 6; a++){
for(int b = 0; b <= 1; b++){
g.drawImage(spells[a][b],1+((b-1)*34),1+((a-1)*34),null);
}
}
}
}
编辑:我得到的错误是:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at p.paintComponent(engine.java:51)
at javax.swing.JComponent.paint(JComponent.java:1045)
at javax.swing.JComponent.paintChildren(JComponent.java:878)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintChildren(JComponent.java:878)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
at javax.swing.JComponent.paintChildren(JComponent.java:878)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5219)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295)
at javax.swing.RepaintManager.paint(RepaintManager.java:1236)
at javax.swing.JComponent.paint(JComponent.java:1031)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:78)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:115)
at java.awt.Container.paint(Container.java:1967)
at java.awt.Window.paint(Window.java:3877)
at javax.swing.RepaintManager$3.run(RepaintManager.java:807)
at javax.swing.RepaintManager$3.run(RepaintManager.java:784)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:784)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:757)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:706)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1647)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at p.paintComponent(engine.java:51)
at javax.swing.JComponent.paint(JComponent.java:1045)
at javax.swing.JComponent.paintChildren(JComponent.java:878)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintChildren(JComponent.java:878)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
at javax.swing.JComponent.paintChildren(JComponent.java:878)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5219)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295)
at javax.swing.RepaintManager.paint(RepaintManager.java:1236)
at javax.swing.JComponent.paint(JComponent.java:1031)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:78)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:115)
at java.awt.Container.paint(Container.java:1967)
at java.awt.Window.paint(Window.java:3877)
at javax.swing.RepaintManager$3.run(RepaintManager.java:807)
at javax.swing.RepaintManager$3.run(RepaintManager.java:784)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:784)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:757)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:706)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1647)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
答案 0 :(得分:7)
BufferedImage 是 一个Image,换句话说,它是从Image抽象类扩展而来的。你不需要转换任何东西。
请查看BufferedImage API了解详情。
修改强>
您在评论中说明:
当我运行此代码时,我在控制台中收到错误信息。它为什么要这样做?当java文件转换为类时,它没有找到错误。
然后,您将要发布您收到的任何错误/异常消息,并指出我们将哪些行抛出。
另外,您将从不想要从paintComponent方法中读取图像。这种方法应该是精益的,卑鄙的,快速的,并且只关注绘画和绘画。当你只需要在构造函数中说一次变量时,为什么要多次读入图像?
编辑2
您的错误是在您的engine.java类的第51行engine.java:51
上发生的NullPointerException。请注意,这与使用BufferedImage与Image有关的无,以及与尝试使用空引用变量有关的一切。我怀疑,问题的关键在于异常消息。在将来的问题中,您需要发布任何和所有异常消息和指示哪一行引发它们。
编辑3
从不 执行此操作:
try{
image = ImageIO.read(new File("spells.png"));
} catch(IOException e) {
}
永远不要将你的catch块留空。至少打印堆栈跟踪。否则,如果发生错误,你将不知道。
编辑4
您在评论中说明:
关于编辑的注意事项:当spritesheet和sprite的声明放在paintComponent方法之外时。代码的20个部分在变量处有不必要的错误,有时候用大括号表示
"engine.java:<line>: class, interface, or enum expected"
从你的错误中,我猜你已经有了调用方法的代码,在任何构造函数或方法之外的类中裸露出来,不属于它。我建议你在类中声明你的Image变量,并在你的构造函数中初始化它(现在它是空的)。
同样,你需要告诉我们哪一行正在抛出异常。
编辑5
您在评论中说明:
第51行是法术[k] [1] = image.getSubimage((34 * 2 * k)-34 * 2,0,34,34);
这就像我在上次评论中猜到的那样。这意味着图像为空,您尝试读取它是错误的。通常这是因为在错误的位置查找文件,或者如果在jar文件中,首先尝试使用文件。您需要考虑将Image作为资源而不是文件。
要进行调试,请尝试简化程序 - 只需创建一个非常小的程序,该程序读入图像,从中创建ImageIcon,并在JOptionPane.showMessageDialog(null, yourIconHere)
中显示ImageIcon。
编辑6
例如,尝试使用以下内容测试代码:
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SimpleTestImage {
public static void main(String[] args) {
String path = "spells.png";
InputStream inputStream = SimpleTestImage.class.getResourceAsStream(path);
try {
BufferedImage img = ImageIO.read(inputStream);
ImageIcon icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, icon);
} catch (IOException e) {
e.printStackTrace();
}
}
}
在这个例子中,我不使用File来获取Image,而是使用InputStream作为类资源。执行此操作时,Java将开始在您拥有类文件的相同位置查找图像。
再次,在类的构造函数中读取Image。