I need to upload an image file and generate a thumbnail for the uploaded file in my JSF webapplication. The original image is stored on the server in /home/myname/tomcat/webapps/uploads, while the thumbnail is stored in /home/myname/tomcat/webapps/uploads/thumbs. I'm using the thumbnail generator class I copied from philreeve.com.
I have successfully uploaded the file with help from BalusC. But using Toolkit.getImage(), I can't access the image.
I used the uploaded file's absolute path, like so:
inFilename = file.getAbsolutePath();
The relevant code from the thumbnail generator is:
public static String createThumbnail(String inFilename, String outFilename, int largestDimension) {
...
Image inImage = Toolkit.getDefaultToolkit().getImage(inFilename);
if (inImage.getWidth(null) == -1 || inImage.getHeight(null) == -1) {
return "Error loading file: \"" + new File(inFilename).getAbsolutePath() + "\"";
}
...
}
Since I am already using the absolute path, I don't understand why it is not working. I have also used the following values for inFilename, but I always get the "Error loading file...".
/home/myname/tomcat/webapps/uploads/filename.ext
/uploads/filename.ext
But I did check the directory, and the image is there. (I uploaded using /home/myname/tomcat/webapps/uploads/filename.ext, and it works.) What is the correct path for the image in that directory? Thank you.
Update
I got the code to work by using:
Image inImage = ImageIO.read(new File(inFilename));
I still don't understand why Toolkit.getImage() does not work though.
Are you sure it's a JPEG file? Use an image viewer to make sure nothing bad happened to the file during upload (or that it was an image to begin with).
Also, use new File(inFilename).exists() to make sure the path is correct. I also suggest to print new File(inFilename).getAbsolutePath() in error messages because relative paths can hurt you.
That said, the rest of the code looks correct.
The problem is that Toolkit.getImage() does not return the image immediately. The issue is well-described in this bug report, a relevant extract of which is here:
This is not a bug. The submitter is not properly using the asynchronous
Image API correctly. He assumes that getImage loads all of the image's bits
into memory. However, it is well documented that the actual loading of
bits does not take place until a call to Component.prepareImage or
Graphics.drawImage. In addition, these two functions return before the
Image is fully loaded. Developers are required to install an ImageObserver
to listen for notification that the Image has been fully loaded. Once they
receive this notification, they can repaint the Image.
I found that the answer to this question works well:
Image image = new ImageIcon(this.getClass().getResource("/images/bell-icon16.png")).getImage();
Related
I am able to show achievement images using the ImageManager from the URI method getUnlockedImageUri but for some reasons, I need to find the local path to the image because I don't want to use the ImageView and I need the actual file path to the image
The URI of Google Play Games achievement looks something like this content://com.google.android.gms.games.background/images/d2bbfba4/61 and I was hoping to be able to convert it to a File object like below:
File myFile = new File(ach.getUnlockedImageUri().getPath());
Log.i(ExConsts.TAG, "myFile.exists() = " + myFile.exists());
// returns false!
But that does not work! any idea why? or what else I should try? or even tell me if it's possible?
A content:// Uri is a clear sign that either
There is no local file
You do not have direct access to the local file
As stated in the getRevealedImageUri() Javadoc:
To retrieve the Image from the Uri, use ImageManager.
You can use ImageLoader.loadImage(OnImageLoadedListener, Uri) to get a Drawable which can be drawn onto a Canvas using Drawable.draw(Canvas).
You can convert a Drawable to a Bitmap using something similar to this answer if you'd like.
I've built a Java application that loads an image at runtime. The location of the image is fixed relative to the project.
I would like to be able to run the program from both within Eclipse and the command line and for it to load the image correctly. However, I can only do one or the other but not both. This seems like such a trivial thing to want to do but I can't find out how to do it.
The project is set up so that it creates a bin directory for the output and puts the image in a resources sub-folder. This is fine when running from the command line as I can write my code to look in that sub folder for the file.
But when I run the program from within eclipse the current working directory is different.
What am I missing?
TIA
Update - adding some code
This is what I had originally:
BufferedImage awtImage = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/image-name.png"));
Following the advice in the comments I am trying to use getResourceAsStream but I don't know what to pass to the File constructor.
InputStream temp = MyClass.class.getResourceAsStream("resources/image-name.png");
BufferedImage awtImage = ImageIO.read(new File(???));
The resource is being found because temp is not null.
I think there's 2 solutions.
1) you specify an absolute path
2) your image is in the classpath so you could load it via :
YouClass.class.getResourceAsStream("YourImg.png");
The working directory, if that's really what you mean, is not a great place to load an image from. It appears that you have an image that you would distribute with your finished program so that the program could use it. In that case, I suggest that you use Class.getResourceAsStream(), and put the image in the directory with (or near) that class.
EDIT:
Here is code I used in one of my programs for a similar purpose:
ImageIcon expandedIcon = null;
// ...
expandedIcon = new ImageIcon(TreeIcon.class.getResource("images/Expanded.png"));
The ImageIcon class is part of Swing; I don't know if you're using that, but this should serve to show you the idea. The getResource() method takes a URL; again, you might need something a little different. But this shows the pathname relative to the path of the class on which the method is called, so if TreeIcon is in x/y/z/icons, the PNG file needs to be in x/y/z/icons/images, wherever that is on that computer.
TreeIcon is a class of mine, and its internals will not help you, so I'm not posting them. All it's doing here is providing a location for the PNG file I'm loading into an ImageIcon instance.
In addition to working on a disk with a directory structure, this also works in a jar file (which is a common way to distribute a java program or library). The jar file is just a zip file, and each file in the jar/zip file has its directory associated with it, so the image can be in the jar in the correct directory just as the java classes are in their directories.
getResourceAsStream() returns a stream; if you want to use that byte stream to load as an image, find a class that converts an stream to something your image class can use as a constructor or in a load method and hook them up. This is a common thing to have to figure out with Java i/o, unfortunately there is no cookbook way to do it across all images and situations, so we can't just tell you what it is.
EDIT 2:
As from the comment, try:
ImageIO.read(new File(MyClass.class.getResource("resources/image-name.png");
I set up my Eclipse projects like this.
The input directory is added to the classpath (JavaBuildPath in Eclipse).
Finally, you access the image and / or text files like this.
private BufferedImage getIconImage() {
try {
return ImageIO.read(getClass().getResourceAsStream(
"/StockMarket.png"));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
I know that the method returns -1 when it couldn't get the width or height of the image, but I hope you can tell me why it can't manage to do that. Here I create a few ImageIcons and save them in an Image Array:
for(int x = 0; x < playerSprites.length; x++){
playerSprites [x] = new ImageIcon("player" + x + ".png").getImage()
}
Later I create an instance of the class which only creates this Array at the moment. When I then want to get the images from the Array in the other class I check their height and width and I always get -1 on both:
public Image nextImage(String name){
Image image = null;
if(name.equals("player")){
if(counter == animationImageManager.getPlayerSprites().length-1){
counter = 0;
}
image = animationImageManager.getPlayerSprites()[counter];
counter++;
}
return image;
}
If image is not found then still it return -1 for height and width.
Try below sample code to reproduce the issue:
System.out.println(new ImageIcon("").getImage().getWidth(null)); // print -1
It's worth reading Java Tutorial on Loading Images Using getResource
May be it's not loading the images properly.
You can try any one based on image location.
// Read from same package
ImageIO.read(getClass().getResourceAsStream("c.png"));
// Read from images folder parallel to src in your project
ImageIO.read(new File("images/c.jpg"));
// Read from src/images folder
ImageIO.read(getClass().getResource("/images/c.png"))
// Read from src/images folder
ImageIO.read(getClass().getResourceAsStream("/images/c.png"))
Read more...
The width/height for Image will return -1 if the image is null. When there's no image.
Suggestions:
use ImageIO.read() which will throw an IOException if something goes wrong with the IO, like the path being wrong.
If the image is a resource for your application, then don't read it as a file, read it as a resource via URL. For instance, if the image is in src/images, then you could do
URL url = getClass().getResource("/images/myimage/png");
BufferedImage image = ImageIO.read(url);
Important thing to note with ImageIcon is when you pass a String to the constructor, it will look for the file in the local file system. It may work when you are developing, but once you deploy the application with the images in the jar, it won't work anymore, with the file path, because it will no longer be valid. You could pass the URL to ImageIcon just the same as above, but like I said, ImageIO allows for more error detection.
Just so you understand what's going on in your current code, by you specifying just the image file name as the path to the ImageIcon, the search will look for the image in the root of the project folder (if you're working in an IDE) because that's the working directory. So if your images aren't there, the images won't be found.
Another thing to note about my second bullet point is how the image is search for. You can see the path I used "/images/myimage/png". What the / in the front does, is bring the search to root of the classpath, which in development view, is the src. The calling class will normally be in some package on the classpath, say com.hello.somepackage.SomeClass. So if SomeClass tries to call the getclass getresource without the /, the search will begin from the location of the class, which is in the package.
The are just some things to consider when using resources/images. But the first couple points should get you going.
Until now I did saving image into the webapp directory and its path into database.
But now am trying to save the image outside of the webapp so that if I deploy my new war files then my old files folder will not be deleted.
From my below code my image file is correctly saving into the specified folder outside of the webapp but i don't know how to retrieve that image into my jsp page.
I tried like this
<img src="www.myproject.com/struts2project/files/smile.jpg/>"
but this is wrong. I am not getting my image to be display into my jsp page.
Below code is working fine for uploading image into absolute path but my problem is how to retrieve that image?
`fileSystemPath= "/files";
try{
File destFile = new File(fileSystemPath, thempicFileName);
FileUtils.copyFile(thempic, destFile);
String path=fileSystemPath+"/"+thempicFileName;
theme=dao.getThemeById(themId);
theme.setThemeScreenshot(path);
theme.setThemeName(theme.getThemeName());
theme.setThemeCaption(theme.getThemeCaption());
dao.saveOrUpdateTheme(theme);
}catch(IOException e){
e.printStackTrace();
return INPUT;
}`
Kindly help me...
I hope I'm being clear on what I need, let me know if I am not and I'll try to explain in another way.
As you say . . . this question describes what you need to do. I guess what you need to know is how to best achieve this with struts 2. Here's what's going on.
In your tag:
That url is being routed to your struts 2 application. Correct? The context is "struts2project".
One of the solutions offered by the referenced question is to use Tomcat's ability to serve static requests and configure tomcat to know about this other document root that holds your images. I think this is a great solution.
If you want to keep it inside of struts2, I think you're best option is to use a dedicated "image streaming from that other place" action that get's an InputStream to the image, then uses the Struts2 Stream Result result type. That result type lets you specify an adhoc InputStream. It also helps you set the appropriate headers. Note, the header values on that documentation page are for downloading the file, so you don't want those values. They would force the browser to open a save as dialog for the image, I think.
You are already using absolute paths, just use a location outside of your web application:
String destinationDir = "/path/to/my/directory/";
File file = new File(destinationDir + item.getName());
I am having some issue trying to create image using createImage() using j2me. The prog will just hang. I am able to get input from file but I can't createImage. Does anyone have any idea?
if (filenames.exists()) {
InputStream input = filenames.openInputStream();
try { Logger.logEventInfo("READING1: " + imageName);
Image image = Image.createImage(input); //Having problem here...
Try using createImage(String name) version of the method if you are just trying to load the data from an image file. Make sure the image is a PNG, and in the resource (res) folder. The String should be in the format "/filename.png" -- note the leading slash.