jar包中图片加载出错解决方案

如果你对eclipse中加载图片不太熟悉的话,恭喜你,看到了这篇文章。

问题:图片加载报错

这个问题其实很简单,因为jar包其实是一种压缩形式,你并不能通过File直接从中读到信息。

解决方案:使用InputStream

        //创建马里奥图片的inputstream对象
        InputStream ma = this.getClass().getResourceAsStream("/mario_g.png");
        //创建路易吉图片的inputstream对象
        InputStream lu = this.getClass().getResourceAsStream("/luigi_g.png");       
        //使用ImageIO.read()方法直接读取成BufferedImage对象 
		BufferedImage marioBufferedImage = ImageIO.read(ma);
		BufferedImage luigiBufferedImage = ImageIO.read(lu);
		//如果你需要的是Image对象的话,只需要强转一下就行了。这里使用BufferedImage因为他可以比较方便的改变图片的大小。
		Image marioImage = (Image)marioBufferedImage;

上面使用的路径,为src的相对路径。
在这里插入图片描述

提升:这样写为什么可以?

我们这个this.getClass().getResourceAsStream显然是从.class文件所在目录中获取文件的,为什么我前面说只要写src的相对路径就行呢?

首先,我们需要明白的是,eclipse在编译的时候,会将src目录下的文件和.java文件一并编译到bin目录下保持不变,而.java文件则被编译成了.class文件。

这样你是不是明白了?咱们获取的的确不是src下的文件,但是bin下的确也有这个文件就是了。

你现在是不是想着把图片放到bin目录下,是不是少放在src下一次,还要更精简一些呢?

然而并不是,首先,你本次运行还是没问题的,因为你bin目录下的确有你放入的文件。但是,只要你修改了java代码,eclipse一重新编译class文件,哼哼,你src目录下没有的,bin目录下也就木大木大啦!而且你这样的话导出成jar包的时候里面会没有你的资源文件。。。

那么这里再稍微讲下如何导出jar包吧,右键项目 -> Java -> JAR file -> Next -> 在 Select the export destination 下点 Browse.. 选一个路径 -> finish

这样你就可以得到一个jar包了,里边只有编译好的class文件嘛,所以相对应的路径,就应该取class文件所在的路径咯,这也是你jar包文件取不到的原因。

言归正传,你可能会想,取class文件所在路径,用this.getClass().getResource("/").getFile()不行吗?然后用得到的字符串,去新建一个File对象,也是在bin里取图片啊,为啥不行?

这就要涉及到读取文件的方式了,InputStream读取方式,是将图片转换成流数据来读取,就好像是文件肚子里的蛔虫。而File的读取方式是先找到文件,再读取,就好像是侦探通过线索来找你。而导出成jar包侦探就找不到你了吗?还真找不到了!因为前面也说了,jar包是一种压缩文件的形式,他是一个文件,不是一个路径,就好像你藏在了一个人的梦里,而侦探又不是什么神仙,怎么可能从别人的梦里找到你?这个解答满意否?

下面再顺便讲讲使用jar包吧,很简单,在项目下新建一个lib目录,然后把你生成的jar包拖进去,右键它,点Build Path -> Add To Build Path就行了,你就可以创建jar包里的类的对象来使用它的方法了。

展示:这里展示下我做的jar包(一个简单的过场动画)

在这里插入图片描述

源码:java代码及图片

这是创建jar包前的源码,创建jar包的时候可以把public class去掉。

import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class GuoChangTest extends JFrame{
    
    
	public GuoChangTest(String title) throws IOException, InterruptedException, URISyntaxException
    {
    
    
        JFrame jf = new JFrame(title);    
        Container conn = jf.getContentPane();    //得到窗口的容器
        DrawGuoChang guochang = new DrawGuoChang(790,580);
        conn.add(guochang);
        jf.setBounds(300,80,800,600); //设置窗口的属性 窗口位置以及窗口的大小
        jf.setVisible(true);//设置窗口可见
        jf.setDefaultCloseOperation(DISPOSE_ON_CLOSE); //设置关闭方式 如果不设置的话 似乎关闭窗口之后不会退出程序
        guochang.run();
    }
    
    public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
    
    
        new GuoChangTest("过场动画测试");        //创建窗口
    }

}

@SuppressWarnings("serial")
class DrawGuoChang extends JPanel{
    
    
	
	private int width;
	private Image marioImage;
	private Image luigiImage;
	private int imgWidth;
	private int imgHeight;
	private int t;
	
	public DrawGuoChang(int width,int height) throws IOException, URISyntaxException {
    
    
		this.width = width;
        InputStream ma = this.getClass().getResourceAsStream("/mario_g.png");
        InputStream lu = this.getClass().getResourceAsStream("/luigi_g.png");        
		BufferedImage marioBufferedImage = ImageIO.read(ma);
		BufferedImage luigiBufferedImage = ImageIO.read(lu);
		imgHeight = height/6;
		double scale = imgHeight/(double)marioBufferedImage.getHeight();
		imgWidth = (int) (marioBufferedImage.getWidth()*scale);
		this.marioImage = marioBufferedImage.getScaledInstance((int) imgWidth,  imgHeight, Image.SCALE_DEFAULT);
		this.luigiImage = luigiBufferedImage.getScaledInstance((int) imgWidth,  imgHeight, Image.SCALE_DEFAULT);
	}
	
	public void run() throws InterruptedException {
    
    
		t=0;
		while(true) {
    
    
			t++;
			Thread.sleep(20);
			super.repaint();
			if(t==-1) {
    
    
				return;
			}
		}
	}
	
	protected void paintComponent(Graphics g) {
    
    
		int xm,xl=1;
		for(int i=0;i<3;++i) {
    
    
			if(t>=0) {
    
    
				xm=-100-imgWidth+t*10;
				xl=100+width-t*10;				
			}else {
    
    
				xm=-100-imgWidth;
				xl=100+width;								
			}
			g.drawImage(marioImage, xm, imgHeight*i*2, null);
			g.drawImage(luigiImage, xl, imgHeight*i*2+imgHeight, null);
		}
		if(xl<=0) {
    
    
			t=-40;
		}
	}
	
}

图片是我自己网上找的图片然后ps做的。
在这里插入图片描述
mario_g.png

在这里插入图片描述
luigi_g.png

猜你喜欢

转载自blog.csdn.net/bdu_zhangAo/article/details/104908556