[java] Mini-tutorial: How to load images from the classpath?

This topic is 4166 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Alright... This gets asked a lot on these forums, so I thought a thread like this might be useful. How do we load images from the classpath? How do we store them in a nice little .jar file? I hope I can help you on that, if you have such doubts. Before starting, let me add that this is how *I* do it, which certainly does not mean this is the *best* way to do it. Any suggestions are welcome and appreciated, but bear in mind that I only wanted to spread a simple and working way of loading images from the classpath and/or from .jar files, since this gets asked a lot on this forum. [grin] First, let's assume the following:
Directory structure
<My Project>
<src>
<lib>
<rsrc>
* image0.png
* image1.png
* image2.png

Where: - src: The folder where all of your own source packages reside. - lib: The folder where all the external .jar files of your application reside. - rsrc: The folder where all of your external resources (i.e, images) reside. I'll soon show you an ant build file to simplify the following process. But to make it short, you can create a .jar file out of your "rsrc" directory with the following command:
jar -cf resources.jar rsrc
This will add the entire "rsrc" folder into a .jar file called "resources.jar". Yes, it is just that simple. Move that new jar file into your "lib" folder, to use it just as any other library you already have there. To actually load the image, you use the following:
Image img = ImageIO.read(getClass().getResource("rsrc/image0.png");
This code uses the class loader to locate and load the file "image0.png"; If the "MyProject" folder is located on the classpath while you run the application, it will also work to load images from the hard disk. When deploying your application, however, it will find the image on the jar file, which is what you should strike for. Another way of ensuring that you use the correct class loader to load the image is the following:
URL rsrcUrl = Thread.currentThread().getContextClassLoader().getResource("rsrc/image0.png");
Image img = ImageIO.read(rsrcUrl);
A very basic ant file I will provide here a very basic ant build file that can be used to build and run your projects within any IDE that supports ant, and obviously, on the command line. I've added ant "code" to do the jar trick mentioned above:
<project name="MyProject" default="build" basedir=".">

<!-- Basic properties -->
<property name="src"        value="src"/>
<property name="lib"        value="lib"/>
<property name="dist"       value="dist"/>
<property name="docs"       value="docs"/>
<property name="jar"        value="MyProject"/>
<property name="build"      value="build/classes"/>
<property name="rsrc"       value="rsrc"/>
<property name="main"       value="org.main.MyMainClass"/>

<!-- Performance properties -->
<property name="memory-min" value="-Xms32m" />
<property name="memory-max" value="-Xmx128m" />

<!-- Allow user to override properties without editing this file -->
<property file="${user.home}/.ant.properties" /> <!-- init --> <target name="init"> <mkdir dir="${build}"/>
<mkdir dir="${dist}"/> <copy todir="${dist}">
<fileset dir="${lib}"> <include name="**/*.jar" /> </fileset> </copy> <!-- Jar the resources (not compressed) --> <jar compress="false" destfile="${lib}/rsrc.jar">
<fileset dir="${rsrc}"> <include name="**/*.*" /> </fileset> </jar> </target> <!-- Clean --> <target name="clean" description=""> <delete dir="${dist}" failonerror="false" />
<delete dir="${build}" failonerror="false" /> <delete file="${lib}/rsrc.jar" />
</target>

<javadoc sourcepath="${basedir}/${src}" destdir="${basedir}/${docs}/javadocs">
<fileset dir="${src}"> <include name="**/*.java" /> </fileset> <!-- For 1.5 API --> <link href="http://java.sun.com/j2se/1.5.0/docs/api/"/> </javadoc> </target> <!-- Compile --> <target name="compile" depends="init" description=""> <javac srcdir="${src}" destdir="${build}" optimize="true" debug="on" > <include name="**/*.java"/> <classpath> <pathelement location="${build}"/>
<pathelement location="${basedir}"/> <fileset dir="${lib}" includes="**/*.jar"/>
</classpath>
</javac>
</target>

<!-- Build -->
<target name="build" depends="compile" description="">
<jar jarfile="${dist}/${jar}.jar" basedir="${build}"> <manifest> <attribute name="Main-Class" value="${main}"/>
</manifest>
</jar>
</target>

<!-- Run -->
<target name="run" depends="init, build" description="">
<java classname="${main}" fork="true" failonerror="true"> <jvmarg value="-server"/> <jvmarg value="${memory-min}"/>
<jvmarg value="${memory-max}"/> <classpath> <pathelement location="${basedir}"/>
<pathelement location="${build}"/> <fileset dir="${lib}" includes="**/*.jar"/>
</classpath>
</java>
</target>

</project>


Hope it helps you out, folks. Post back with doubts, if you're left with any ;) Son Of Cain