so I'm looking towards porting a .jar to an executable and am cleaning my code up a bit before I do that. Right now I have the following:
BufferedImage bgImg = null;
//Grabs the background image
try {
bgImg = ImageIO.read(new File(""));
} catch (IOException e1) {
e1.printStackTrace();
}
I have several other images that I can just use:
new ImageIcon(getClass().getResource("imagename.png")));
However, since the former is a File object it does not take the same type of argument. I was wondering if there is something similar that I can use for that, or if there is some other way to make the File absolute so that there are no errors when porting to an executable. Thanks!
Use the read(InputStream input) method instead with Class.getResourceAsStream().
For example:
bgImg = ImageIO.read(getClass().getResourceAsStream("imagename.png"));
I'm not sure what you want to do. But you can access a file in your current working directory with a dot before the path.
E.g.
ImageIO.read(new File("./imagename.png"));
Related
I'm using a custom method to get pictures from the resources/ folder. The hardcoded path works well when programming during production (src/main/resources/). However when delivering, I would need to make this path relative to the .jar root. So I made this.
public static Image getImageFromFile(String file)
{
Image image = null;
try
{
String path = FileUtils.class.getClassLoader().getResource(file).toExternalForm();
System.out.println(path);
File pathToFile = new File(path);
image = ImageIO.read(pathToFile);
}
catch (IOException ex) {ex.printStackTrace();}
return image;
}
file:/C:/Users/Hugo/Desktop/Hugo/Java%20Workspace/ClashBot/bin/main/icons/level-label.png
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at com.lycoon.clashbot.utils.FileUtils.getImageFromFile(FileUtils.java:55)
The printed path is valid and points to the corresponding picture. However, the program raises an IOException.
Why can't it find the file?
You're jumping through way too many hoops. It's quite simple:
FileUtils.class.getResource("path.png");
// -OR-
try (var in = FileUtils.class.getResourceAsStream("path.png")) {
// in is an inputstream.
}
is all you need. Note that this means the path.png file is searched for in the exact same place (and even same 'subdir') as where FileUtils lives. So if you have, say, a file on C:\Projects\Hugo\MyApp\myapp.jar, and if you were to unzip that, inside you'd find com/foo/pkg/FileUtils.class, then the string path.png would look in that jar, and for com/foo/pkg/path.png. In other words, AnyClass.class.getResource("AnyClass.class") will let a class find its own class file. If you want to go from the 'root' of the jar, add a slash, i.e. FileUtils.class.getResource("/path.png") looks in the same jar, and for /path.png inside that jar.
getResource returns a URL. getResourceAsStream returns a stream (which you need to close; use try-with-resources as I did). Just about every resource-using API out there will take one of these two as input. For example, ImageIO does so; it even takes a URL so you can use either one:
var image = ImageIO.read(FileUtils.class.getResource("imgName + ".png"));
Yes. It's a one-liner. This will load images straight from within a jar file!
You could try to use a slightly different call like this:
java.net.URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(file);
String filePath = URLDecoder.decode(fileUrl.getPath(), "UTF-8");
image = ImageIO.read(filePath);
This is a question that has been asked like 100 times on this site, but I have looked at all of them and even though they all were solved, none of the solutions worked for me.
Here's what my code looks like:
public Button1(Client client, String imgName) {
this.client = client;
try {
this.icon = ImageIO.read(this.getClass().getResourceAsStream("/resources/" + imgName));
} catch (IOException e) {
e.printStackTrace();
}
When the code runs it results in the following error:
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
The string imgName is passed to the constructor from a child class and is the name of an image (e.g. image.png). I also have made sure that my resources folder is in the root of the project folder, and is included as a source folder in the eclipse project. I've also made sure that System.getProperty("user.dir") points to the correct location. I have also tried using getResource() instead of getResourceAsStream(), but it still does not work.
Try using this:-
this.icon = ImageIO.read(new FileInputStream("res/test.txt"));
where res folder is present at the same level as your src folder. Also, if you notice, the slash / before the res folder name was removed.
I know this is pretty old, but I just had the same issue.
Check to make sure that your image extensions aren't capital.
In my resources folder for images I had "enemy.PNG", but I was trying to load "enemy.png" which you would think would work but doesn't.
so, just make your extensions aren't capitalized.
I solved mine by changing my code from this
image = ImageIO.read(SpriteSheet.class.getResourceAsStream("res/image.png"));
to this
image = ImageIO.read(SpriteSheet.class.getResourceAsStream("/image.png"));
Hope this helps.
The path passed as the argument to getResourceAsStream() should be relative to the classpath set.
So try changing this
this.icon = ImageIO.read(this.getClass().getResourceAsStream("/resources/" + imgName));
to
this.icon = ImageIO.read(this.getClass().getResourceAsStream("resources/" + imgName));
This may come as a "No, Duh!" to many on this site, but it is always important to point out how literal Java is. Case sensitivity is key, especially if you .jar a file.
If your program works fine with compiling and then running but suddenly is getting this issue when you .jar your files. Make sure to check you Case on your folders / files and your references in your code. (As well as make sure they are in your .jar)
Hope this helps anyone that ends up here looking at the same issue.
Try this:
this.icon = ImageIO.read(this.getClass().getResource("/resources/" + imgName));
Try using the following
this.icon = ImageIO.read(this.getClass().getResourceAsStream("../resources/" + imgName));
Is the resource folder a class folder in eclipse? Right click on the project -> Properties -> Java Build Path -> Libraries -> Add Class Folder... -> (select the res folder) and add it as a class folder.
I was facing this error due to a bug in my code. I was trying to extract (conn.getInputStream()) from a different connection object than what it should have been. I fixed the connection object variable and it started working.
BufferedImage image;
try (InputStream in = new BufferedInputStream(conn.getInputStream())) {
image = ImageIO.read(in);
File file = new File(fullImageFilePath);
synchronized (file.getCanonicalPath().intern()) {
if (!file.exists()) {
ImageIO.write(image, "png", file);
}
}
}
Instead of
this.icon = ImageIO.read(this.getClass().getResourceAsStream("/resources/" + imgName));
Use
this.icon = ImageIO.read(new File("Full Path");
I do not know why the first snippet does not work, but new File() has always worked for me.
You can try this:
image = ImageIO.read(getClass().getResource("/resources/" + imgName));
Try This
private BufferedImage get(String path) throws IOException{
URL url = this.getClass().getClassLoader().getResource(path);
String thing = url.getFile();
return ImageIO.read(new File(thing));
}
When ever I make a JAR, the JAR won't read the folder inside it, only a folder in the folder the JAR is it. OK, that wasn't very descriptive. So here is a photo I edited to support.
I hope you get the idea now. So how would I fix this? I already have res and stats part of the build path in eclipse, now what?
Code I use to read the resources:
Image player;
player = new ImageIcon("res/player.png").getImage();
When using ImageIcon and passing it a String, it expects that the parameter refers to a File.
From the JavaDocs
Creates an ImageIcon from the specified file. ... The specified String
can be a file name or a file path
Files and "resources" are different things.
Instead, try using something more like...
new ImageIcon(getClass().getResource("res/player.png"));
Assuming that res/player.png resides within the jar in side the res directory.
Depending on the relationship to the class trying to load the resource and the resource's location, you may need to use
new ImageIcon(getClass().getResource("/res/player.png"));
instead...
Updated
Some recommendations, as EJP has pointed, you should be prepared for the possibility that the resource won't be found.
URL url = getClass().getResource("/res/player.png");
ImageIcon img = null;
if (url != null) {
img = new ImageIcon(url);
}
// Deal with null result...
And you should be using ImageIO.read to read images. Apart from the fact that it supports more (and can support more into the future) image formats, it loads the image before returning and throws an IOException if the image can't be read...
URL url = getClass().getResource("/res/player.png");
ImageIcon icon = null;
if (url != null) {
try {
BufferedImage img = ImageIO.read(url);
icon = new ImageIcon(img);
} catch (IOException exp) {
// handle the exception...
exp.printStackTrace();
}
}
// Deal with null result...
I am trying to read some image files jpg, tif, gif, png and need to save files and create icons.
And i am getting UnsupportedTypeException.
ImageIO.read(file);
If i use following line, as earlier discuss in form.
BufferedImage img = JPEGCodec.createJPEGDecoder(inputStream).decodeAsBufferedImage();
I get JPEGCodec cannot found symbol.
I am using netbean 7.0.1. I have also added jai-imageio.jar.
By default, ImageIO can only read JPG, GIF and PNG file formats, if I remember right. To add new formats like TIFF, you need to add a plugin, which is a jar file, to your classpath, and to add an ImageIO.scanForPlugins() to you code before you try to read a file.
Example of plugin:
http://ij-plugins.sourceforge.net/plugins/imageio/
Try "ImageIO plugins" in Google.
JAI-ImageIO does include plugins for file formats like TIFF, so in principal what you are trying to do should work. However, to install JAI-ImageIO it's not enough to add it to your classpath. See the complete installation instructions here: http://java.sun.com/products/java-media/jai/INSTALL-jai_imageio_1_0_01.html
Fr detail we can see the like
http://www.randelshofer.ch/blog/2011/08/reading-cmyk-jpeg-images-with-java-imageio/
Image img = null;
ImageInputStream iis = new FileImageInputStream(file);
try {
for (Iterator<ImageReader> i = ImageIO.getImageReaders(iis);
img == null && i.hasNext(); ) {
ImageReader r = i.next();
try {
r.setInput(iis);
img = r.read(0);
} catch (IOException e) {}
}
} finally {
iis.close();
}
return img;
Java advance image io also solve the problem, but its hard to maintain to install on all plateform.
I have a Java project with a toolbar, and the toolbar has icons on it. These icons are stored in a folder called resources/, so for example the path might be "resources/icon1.png". This folder is located in my src directory, so when it is compiled the folder is copied into bin/
I'm using the following code to access the resources.
protected AbstractButton makeToolbarButton(String imageName, String actionCommand, String toolTipText,
String altText, boolean toggleButton) {
String imgLocation = imageName;
InputStream imageStream = getClass().getResourceAsStream(imgLocation);
AbstractButton button;
if (toggleButton)
button = new JToggleButton();
else
button = new JButton();
button.setActionCommand(actionCommand);
button.setToolTipText(toolTipText);
button.addActionListener(listenerClass);
if (imageStream != null) { // image found
try {
byte abyte0[] = new byte[imageStream.available()];
imageStream.read(abyte0);
(button).setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(abyte0)));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
imageStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else { // no image found
(button).setText(altText);
System.err.println("Resource not found: " + imgLocation);
}
return button;
}
(imageName will be "resources/icon1.png" etc). This works fine when run in Eclipse. However, when I export a runnable JAR from Eclipse, the icons are not found.
I opened the JAR file and the resources folder is there. I've tried everything, moving the folder, altering the JAR file etc, but I cannot get the icons to show up.
Does anyone know what I'm doing wrong?
(As a side question, is there any file monitor that can work with JAR files? When path problems arise I usually just open FileMon to see what's going on, but it just shows up as accessing the JAR file in this case)
Thank you.
I see two problems with your code:
getClass().getResourceAsStream(imgLocation);
This assumes that the image file is in the same folder as the .class file of the class this code is from, not in a separate resources folder. Try this instead:
getClass().getClassLoader().getResourceAsStream("resources/"+imgLocation);
Another problem:
byte abyte0[] = new byte[imageStream.available()];
The method InputStream.available() does not return the total number of bytes in the stream! It returns the number of bytes available without blocking, which is often much less.
You have to write a loop to copy the bytes to a temporary ByteArrayOutputStream until the end of the stream is reached. Alternatively, use getResource() and the createImage() method that takes an URL parameter.
To load an image from a JAR resource use the following code:
Toolkit tk = Toolkit.getDefaultToolkit();
URL url = getClass().getResource("path/to/img.png");
Image img = tk.createImage(url);
tk.prepareImage(img, -1, -1, null);
The section from the Swing tutorial on How to Use Icons shows you how to create a URL and read the Icon in two statements.
For example in a NetBeans project, create a resources folder in the src folder. Put your images (jpg, ...) in there.
Whether you use ImageIO or Toolkit (including getResource), you must include a leading / in your path to the image file:
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/agfa_icon.jpg"));
setIconImage(image);
If this code is inside your JFrame class, the image is added to the frame as an icon in your title bar.