Accessing an Image outside of a jar from inside a jar - java

I tried searching for similar answers but I'm still facing a few difficulties. I'm trying to access a .gif from inside a jar. My file structure is:
src
|-> main
|->webapp
|->images
|-> bulb.gif
|->signed.jar
If I use an absolute file path then I can grab my image by just using return (new ImageIcon(path, description)).getImage(); but I'm trying to just use relative paths. I tried using return (new ImageIcon(getClass().getResource("/images/bulb.gif"))).getImage(); but that didn't work. Am I using the correct pathway in the latter method, or is there a better alternative?
EDIT: I also tried below with no success.
InputStream image = getClass().getClassLoader().getResourceAsStream("images/bulb.gif");
Image in = null;
try {
in = ImageIO.read(image);
}
catch(Exception e){
}
return (new ImageIcon(in, description)).getImage();
My file structure is pertaining to the question is
project/src/main/java/web/load/jar/something.java
project/src/main/java/web/load/jar/images/bulb.gif
project/build.xml
project/target/thing.signed.jar
for my jar and
mainproject/src/main/app/thing.signed.jar
mainproject/src/main/app/images/bulb.gif
for my main webapp. I was trying to access bulb.gif from my signed.jar but it might be easier to just put it in my signed.jar.

Related

javafx - load image from within a jar

I'm sorry for asking such a beginner question, but I just can't get it to work and I can't find the answer anywere either.
I want to have an image inside my .jar file and load it. While that sounds simple, I was only able to load an image while running from inside the IDE but not anymore after making the .jar (Thanks to google I was able to get the .png inside the .jar). Here is what I tried:
BorderPane bpMain = new BorderPane();
String fs = File.separator;
Image imgManikin;
try {
imgManikin = new Image(
Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().toString()+"\\manikin.png");
bpMain.setBottom(new Label(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().toString()+"\\manikin.png"));
} catch (URISyntaxException e) {
imgManikin = new Image(
Main.class.getProtectionDomain().getCodeSource().getLocation().getPath()+"\\manikin.png");
System.out.println(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath()+"\\manikin.png");
bpMain.setBottom(new Label(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath()+"\\manikin.png"));
}
//Image imgManikin = new Image("file:src\\manikin.png");
ImageView imgvBackground = new ImageView(imgManikin);
imgvBackground.setFitWidth(100);
imgvBackground.setPreserveRatio(true);
bpMain.setCenter(imgvBackground);
primaryStage.setTitle("Kagami");
primaryStage.setScene(new Scene(bpMain, 300, 275));
primaryStage.show();
Needlessly to say it didn't work. It is showing me the Label at the bottom with the path just as intended, but it seams like the path just isn't right. (I also tried using the File.seperator instead of \\ and even /, but I got the same result every time: It showes me the path but won't load the image.
I'm using Windows 7, the IDE is IntelliJ and I have the newest Java update.
If the jar file is on the classpath of your application and the image to be loaded is located at the root of the jar file, the image can be loaded easily by:
URL url = getClass().getResource("/manikin.png");
BufferedImage awtImg = ImageIO.read(url);
Image fxImg = SwingFXUtils.toFxImage(awtImg, new Image());
Image fxImgDirect = new Image(url.openStream());
While ImageIO returns a BufferedImage this can be converted to a fx Image using the SwingUtils. However the preferred way is to directly create a new Image instance using the InputStream from the URL.
See also Load image from a file inside a project folder. If done right it does not matter if it is loaded from a jar file or the local file system.
The Image::new(String) constructor is looking for a URL. It is possible to construct a URL for a resource in a jar file, but it's much easier to use ClassLoader::getResource or ClassLoader::getResourceAsStream to manage that for you.
Given the file structure:
src/
SO37054168/
GetResourceTest.java
example/
foo.txt
The following, packaged as a jar will output
package SO37054168;
public class GetResourceTest {
public static void main(String[] args) {
System.out.println(GetResourceTest.class.getClassLoader().getResource("example/foo.txt"));
System.out.println(GetResourceTest.class.getClassLoader().getResourceAsStream("example/foo.txt"));
}
}
jar:file:/home/jeffrey/Test.jar!/example/foo.txt
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream#7f31245a
Note how the URL for the resource is not the same as the URL you were trying to construct. The protocol is different, and you need to have the ! after the path to the jar file.

Unable to locate/open image inside exported jar

I have explored every single solution related to this problem on Stack Overflow, and the solutions I encountered worked only in my IDE (Eclipse Mars), but when exported they all failed.
I have an image file I simply want to load from inside my exported jar.
As you can see from the project layout, Images is a folder directly inside of the project folder CooldownTrackerJava. To refer to it, I've tried a variety of methods.
//My class' name is AddItemDialog
//Method 1
String filePath = File.separator + "Images" + File.separator + "questionMark.png";
InputStream inputStream = AddItemDialog.class.getResourceAsStream(filePath);
BufferedImage img = ImageIO.read(inputStream);
I tried method 1 in a few ways. I tried it with and without the File.separator at the start of the filePath. I understand that the former refers to an absolute path, while the latter is relative. I also tried moving the Images folder inside of the directory where my class files were.
All of these failed giving me a NullPointerException when exported and tested multiple times.
//Method 2
String saveLocation = File.separator + "Images" + File.separator + "questionMark.png";
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(saveLocation));
As per this post I tried the above method however it still did not work.
I've tried many variations aside from the ones mentioned in this post but none of them have been successful when I exported the jar.
Do I need to add the Images folder to my build path? Should I move it to the src folder? Am I missing one obvious step? All suggestions would be highly appreciated. Also here is the layout of the exported jar file.
The solution was a two-part effort. Firstly, I moved my Images folder into the src directory as shown below. Kudos to Matthew.
I then removed File.separator and replaced it with a forward slash/. Thanks to fge.
Do not use File.separator(). Separators for resource paths on the class path is always /. If you use Windows you will therefore always get the wrong result.
I used a variant of method 1 to test it. Both methods will work though.
String saveLocation = "/Images/questionMark.png";
InputStream inputStream = this.getClass().getResourceAsStream(saveLocation);
try {
BufferedImage img = ImageIO.read(inputStream);
} catch (IOException e) {
e.printStackTrace();
}

Reference resource in top directory (not package) in Java JAR/Eclipse

I'm trying to access some resources located in the top directory of my (Java) project (/resources/imgname.jpg) from a class 'GUI' located in a package 'gui'.
Originally I used the following code:
ImageIcon image = new ImageIcon("./resources/imgname.jpg");
Image img = image.getImage();
This works fine in Eclipse, but doesn't display the image when it's in a runnable JAR. So after some searching it seems you need:
InputStream resource = GUI.class.getResourceAsStream("./resources/imgname.jpg");
try {
Image image = ImageIO.read(resource);
} catch (IOException e) {//trycatch needed because of read method}
Now this doesn't work in either Eclipse or JAR.
I've tried changing reference and location, but the only way I can get the image to display is by placing it in the 'gui' package folder. So is there any way I can reference it in the top folder of the project instead (so I don't have to move the resources to 'gui')?
Thx,
Magic
Try this.
InputStream resource = GUI.class.getClassLoader().getResourceAsStream("resources/imgname.jpg");
It works for me.

Changing the location of files in Java application

I've been putting all of my images for my Java application in a package called "rtype" inside src where I also also have my Class that deals with these images. I wanted to sort the images and put them in a folder of their own. When I do this, The images will no longer load into the class, and I know it's because I changed the file path. I've done some research and tried a few different things. This is basically what I had originally:
String walkingDown = "WalkingDown.gif";
ImageIcon ii;
Image image;
ii = new ImageIcon(this.getClass().getResource(walkingDown));
image = ii.getImage();
and It worked just fine before I moved the location of the images outside the location of the class. Now it cant find the images. Here is what I tried and found online to try (The folders Name is Sprites):
//use getClassLoader() inbetween to find out where exactly the file is
ii = new ImageIcon(this.getClass().getClassLoader().getResource(standingDown));
and
//Changing the path
String walkingDown = "src\\Sprites\\WalkingDown.gif";
//also tried a variation of other paths with no luck
I am using the C drive, but don't want to use "C" in my extension, as I want it to be accessible no matter where I put the project. I am fairly stuck at this point and have done enough looking into it to realize that It was time to ask.
I have a separate "package" for images with that name (in the src folder)
Try something like this:
try {
ClassLoader cl = this.getClass().getClassLoader();
ImageIcon img = new ImageIcon(cl.getResource("images/WalkingDown.gif"));
}
catch(Exception imageOops) {
System.out.println("Could not load program icon.");
System.out.println(imageOops);
}
Your variable is named walkingDown, but you pass in standingDown to the getResource() method.
new ImageIcon("src/Sprites/WalkingDown.gif");

How to set icon image for swing application?

I've seen many different examples showing how to set a JFrame's IconImage so that the application uses that icon instead of the standard coffee mug. None of them are working for me.
Here's "my" code (heavily borrowed from other posts and the internet at large):
public class MyApp extends JFrame
{
public MyApp()
{
ImageIcon myAppImage = loadIcon("myimage.jpg");
if(myAppImage != null)
setIconImage(myAppImage.getImage());
}
private ImageIcon loadIcon(String strPath)
{
URL imgURL = getResource(strPath);
if(imgURL != null)
return new ImageIcon(imgURL);
else
return null;
}
}
This code fails down in loadIcon when making a call to the getResource() method. To me, there's only 2 possibilities here: (1) the myImage.jpg is in the wrong directory, or (2) getResource() doesn't like something about my image (I had to convert it from CMYK to RGB in Photoshop so I could use the same image elsewhere with ImageIO.)
I have used the System.out.println(new File(".").getAbsolutePath()); trick to locate the directory where the image JPG should be stored, and still nothing worked. I have subsequently placed the JPG in just about every directory inside my project, just to rule file location out as the culprit.
So that leaves me to believe there's something that getResource() doesn't like about the JPG itself. But I have now already exhausted my understanding of images and icons in the mighty, wide world of Swing.
My JPG loads fine in other image viewers, so that's ruled out as well. Anyone have any ideas?
Thanks in advance!
I have tried following which was a answer for same kind of question like yours. And it works for me.
Try putting your images in a separate folder outside of your src
folder. Then, use ImageIO to load your images. (answered Aug 27 '13 at 0:18
AndyTechGuy)
frame.setIconImage(ImageIO.read(new File("res/icon.png")));
put the image in the root of the classpath and say getResource("classpath:myimage.jpg");
The problem with your code is that jvm is unsure where to lookup the image file so its returning null.
Here is a nice link about classpath
It should be
if(imgURL != null)
^
instead of
if(imgURL !- null)
and
URL imgURL = this.getClass().getResource(strPath);
instead of
URL imgURL = getResource(strPath);
Then it works fine, if "myimage.jpg" is in the same dir with MyApp.class
Two suggestions:
Try using the getClass().getResource("x.jpg"), and putting the file directly in the same folder as the .class file of the class you are in.
Make sure the name is identical in case - some operating systems are case sensitive, and within a JAR, everything is case sensitive.
You can try to use a "/" before your filename.
getClass().getResource("/myimage.jpg")
If you look into your build-output folder (target) you can look for your class where you are trying to get your resource from.
Your resources will probably be copied in some folders above.
For example your target directory could look like this:
target
|- de.example.app
|- Main.class
|- Main-x.y.z.jar
|- myimage.jpg
So if you just go for getClass().getResource("myimage.jpg") it will look under the folder target/de/example/app and won't find a jpg there.
You need to tell him that you want to look under the root-folder (target/**). That's why you need to place a "/" before your file.

Categories

Resources