BufferedImage / Image Conversion

时间:2014-06-01 23:47:37

标签: java image swing

使用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)

1 个答案:

答案 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。