Results 1 to 12 of 12
Thread: Help with moving jpeg files
- 09-27-2009, 10:46 PM #1
Member
- Join Date
- Sep 2009
- Posts
- 10
- Rep Power
- 0
Help with moving jpeg files
My main purpose with this program is to move all my jpeg files to different folders depending on it's resolution, for example, if a certain file has 1920x1200 in resolution, then that file should be moved to the folder called 1920x1200. and so on. However, when running the file, the folders are createn but no files are moved.Java Code:import com.sun.image.codec.jpeg.*; import java.awt.Image; import java.io.*; import java.util.*; public class Sortimages { public static void main(String[] args) throws Exception { File images = new File("H:\\Documents and Settings\\Administrator\\My Documents\\My Pictures\\Wallpapers\\Unidentified"); File[] files = images.listFiles(); File newfile; Image image; for (int i = 0; i < files.length; i++) { image = JPEGCodec.createJPEGDecoder(new FileInputStream(files[i])).decodeAsBufferedImage(); int width = image.getWidth(null); int height = image.getHeight(null); File folder = new File("H:\\Documents and Settings\\Administrator\\My Documents\\My Pictures\\Wallpapers\\" + width + "x" + height + "\\"); folder.mkdir(); if ((i + 1) < 10) { newfile = new File(folder, "Picture - 00" + (i + 1) + ".jpg"); } else if ((i + 1) < 100) { newfile = new File(folder, "Picture - 0" + (i + 1) + ".jpg"); } else { newfile = new File(folder, "Picture - " + (i + 1) + ".jpg"); } files[i].renameTo(newfile); } } }
Can anyone see what I'm doing wrong?
- 09-28-2009, 10:13 AM #2
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
I think renameTo returns a boolean flag on success. Check what it's returning.
I expect you could also use NumberFormat to do the numbering of your files rather than that if/elsif/else block. Not that that's your problem.
- 09-28-2009, 01:50 PM #3
Member
- Join Date
- Sep 2009
- Posts
- 10
- Rep Power
- 0
I added that in the end of the for loop. When I run the file I get the message for every file.Java Code:boolean success = files[i].renameTo(newfile); if (!success){ System.out.println("RenameTo did not success");
If I change it to files[i-1].renameTo(newfile) and start the i value with 1, then almost every file will be moved, of course to wrong folder that is.
For me it seems like the JPEGDecoder of a particular file must be closed before its name can be changed, however I don't see any option to do that, so I changed the code a bit again.
This works fine, although the last file doesn't move.Java Code:import com.sun.image.codec.jpeg.*; import java.awt.Image; import java.io.*; public class Sortimages { public static void main(String[] args) throws Exception { File images = new File("H:\\Documents and Settings\\Administrator\\My Documents\\My Pictures\\Wallpapers\\Unidentified"); File[] files = images.listFiles(); File newfile; File[] folder = new File[files.length]; Image image; for (int i = 0; i < files.length; i++) { image = JPEGCodec.createJPEGDecoder(new FileInputStream(files[i])).decodeAsBufferedImage(); int width = image.getWidth(null); int height = image.getHeight(null); folder[i] = new File("H:\\Documents and Settings\\Administrator\\My Documents\\My Pictures\\Wallpapers\\" + width + "x" + height + "\\"); folder[i].mkdir(); } for (int i = 0; i < files.length; i++) { if ((i) < 10) { newfile = new File(folder[i], "Picture - 00" + (i + 1) + ".jpg"); } else if ((i) < 100) { newfile = new File(folder[i], "Picture - 0" + (i + 1) + ".jpg"); } else { newfile = new File(folder[i], "Picture - " + (i + 1) + ".jpg"); } boolean success = files[i].renameTo(newfile); if (!success) { System.out.println("RenameTo did not success for " + folder[i]); } } } }
Can you see why? Because I don't see any thing that could be wrong.
- 09-28-2009, 02:26 PM #4
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
By "doesn't move" do you mean the success flag is false?
If that's the case then it's because (as you guessed earlier) the stream is still opne (the false is due to, essentially, the file being used). It's open because you have declared "image" outside the loop.
Declare it inside the loop:
The other option (since this is possibly now relying on some garbage collection or finaliser) is also to declare the FileInputStream explicitly so you can close it after each cycle round the loop. In fact that might allow you to stick all the code back into the one loop again.Java Code:for (int i = 0; i < files.length; i++) { Image image = JPEGCodec.createJPEGDecoder(new FileInputStream(files[i])).decodeAsBufferedImage(); ...etc etc...
Java Code:for() { FileInputStream fis try { // add code to open the stream here. image = JPEGCodec.createJPEGDecoder(fis).decodeAsBufferedImage(); ... etc etc. ... move the files (rename). } catch stuff {} finally {close the stream} }
- 09-28-2009, 06:45 PM #5
Member
- Join Date
- Sep 2009
- Posts
- 10
- Rep Power
- 0
By "doesn't move" I mean that the success flag is false, as you said.
I don't really understand what try, catch and finally does, and when I tried to do something about it I just failed so whatever.
But I tried your first option, declaring Image inside the loop, I don't know why I didn't do that in first place, however only doing that didn't seem to work, so I also declared FileInputStream outside the loop and closed it at the end of the loop.
The code looks like this now:
I'm not sure if it works perfectly now, but all images is moved in any case, so Thanks a lot!Java Code:import com.sun.image.codec.jpeg.*; import java.awt.Image; import java.io.*; import java.util.*; public class Sortimages { public static void main(String[] args) throws Exception { String imagespath = "H:\\Documents and Settings\\Administrator\\My Documents\\My Pictures\\Wallpapers\\Unidentified"; String newimagespath = "H:\\Documents and Settings\\Administrator\\My Documents\\My Pictures\\Wallpapers\\"; String maintitle = "Picture"; File images = new File(imagespath); File[] files = images.listFiles(); File[] folder = new File[files.length]; File newfile; FileInputStream fis; for (int i = 0; i < files.length; i++) { fis = new FileInputStream(files[i]); Image image = JPEGCodec.createJPEGDecoder(fis).decodeAsBufferedImage(); int width = image.getWidth(null); int height = image.getHeight(null); folder[i] = new File(newimagespath + "\\" + width + "x" + height + "\\"); folder[i].mkdir(); fis.close(); } for (int i = 0; i < files.length; i++) { int inumber = 1; //Doing this if somehow the picture title would be the same next time I move a file to the specific folder. Don't know if it works yet though. while (inumber < 100) { if (new File(folder[i], maintitle + " - 00" + (i + inumber) + ".jpg").exists() || new File(folder[i], maintitle + " - 0" + (i + inumber) + ".jpg").exists() || new File(folder[i], maintitle + " - " + (i + inumber) + ".jpg").exists()) { inumber++; } else { break; } } if ((i + inumber) < 10) { newfile = new File(folder[i], maintitle + " - 00" + (i + inumber) + ".jpg"); } else if ((i + inumber) < 100) { newfile = new File(folder[i], maintitle + " - 0" + (i + inumber) + ".jpg"); } else { newfile = new File(folder[i], maintitle + " - " + (i + inumber) + ".jpg"); } boolean success = files[i].renameTo(newfile); if (!success) { System.out.println("RenameTo did not success for " + folder[i]); } } } }
- 09-29-2009, 12:01 AM #6
Member
- Join Date
- Sep 2009
- Posts
- 10
- Rep Power
- 0
Sorry for double post, but after running the program on different folders, I now realize I need to do this for PNG images too. So I found the javax.imageio.ImageIO after some googleing.
The code at the for loop looks like this now:
However when running the file I get this error:Java Code:FileInputStream fis; for (int i = 0; i < files.length; i++) { fis = new FileInputStream(files[i]); Image image = ImageIO.read(fis); int width = image.getWidth(null); int height = image.getHeight(null); folder[i] = new File(newimagespath + "\\" + width + "x" + height + "\\"); folder[i].mkdir(); fis.close(); }
Exception in thread "main" java.lang.NullPointerException
at sortimages2.Sortimages2.main(Sortimages2.java:26)
Java Result: 1
BUILD SUCCESSFUL (total time: 31 seconds)
line 26 points at:
int width = image.getWidth(null);
There are 317 files in my folder and the error always happen for the 306th file, so I thought that file 306 might have been bad or something. But even though I delete it I get the same error at the 306th file.
If I delete every file but the first, I will still get the error!
How come this happens and what might be the cause?
Also, all folders are createn until the error occurs.
- 09-29-2009, 09:21 AM #7
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
Resources (eg streams, connections, that sort of thing) should be opend in a try/catch block, and closed in a finally block. This is all to ensure that, even if an exception is thrown, any resources used are closed. Resource leakage in long running systems is one of the main causes of systems grinding to a halt.
Here's the Sun tutorial on Exceptions. In your case it would probably be simply a try/finally block. It's more a good habit to get into than anything that will stop your code from working at the moment.
However because you are now using ImageIO (which I should have thought of earlier, to be honest), don't use a stream. May as well simply give it a File and let ImageIO do all the work. Save you a couple of lines of code.
That exception implies that image is null in that instance. Chuck some debug comments around that loop (System.out.println()). Or step through it in a debugger. Comments might be quicker, though.
- 09-29-2009, 12:44 PM #8
Member
- Join Date
- Sep 2009
- Posts
- 10
- Rep Power
- 0
Can you post an example of a debug comment? I don't really know what you mean there.
But I did use System.out.println(i) at the end of the loop to ensure where exactly the image is null.
As I stated before, the error is not because of the images, It just occurs on a certain number. If I delete 10 files in the beginning then the error would still occur on the 306th image even though that image is completely different this time.
- 09-29-2009, 01:16 PM #9
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
OK, taking your code as a start point (I've changed the input stream to a File).
That's all you should need. It'll tell you exactly which files it's failing on.Java Code:for (int i = 0; i < files.length; i++) { System.out.println("processing file " + files[i]); Image image = ImageIO.read(new File(files[i])); if (image == null) System.out.println("FAILED - " + files[i]); int width = image.getWidth(); // Don't need a parameter for these. int height = image.getHeight(); folder[i] = new File(newimagespath + "\\" + width + "x" + height + "\\"); folder[i].mkdir(); }
I suspect it's a non-graphic file, which might be hidden.
If that's the case, you'll need to check for file extension (and check it is a file, could be it's a directory).
- 09-29-2009, 03:50 PM #10
Member
- Join Date
- Sep 2009
- Posts
- 10
- Rep Power
- 0
I must have a parameter for image.getWidth(); or else I get this error.
getWidth(java.awt.image.ImageObserver) in java.awt.Image cannot be applied to ()
incompatible types
found: java.awt.Image.getWidth
required: int
But I ran the file anyway and it seems Thumbs.db was the problem, I don't know why those are createn. I can't find them in the folder even though I show hidden files for all folders.
Anyway, when I moved the files to a different folder, I got no NullPointerException as expected. So thank you!
Now I'm more interressted in doing this, but I don't really understand the NumberFormat class so I don't know which method to use.
Also, is it possible to store a number greater than 2^64?
Not that this program is going to use such big numbers, but it's something I've wondered for a long time.
- 09-29-2009, 05:22 PM #11
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
Of course, sorry.
You're using Image, not BufferedImage. ImageIO.read(File) returns a BufferedImage, so you could use that and not have to pass null.
As for numbers, BigInteger for large integers, and BigDecimal for large decimals (and maths that doesn't suffer from floating point problems).
For NumberFormat you want to getInstance() to get a formatter to use, set the minimum number of digits for an integer, and you won't want grouping. Then you can format(int), which will give you a String.
See the API. Give it a shot. Declare the formatter otuside of the loop as well, since you only need the one.
- 09-30-2009, 01:11 AM #12
Member
- Join Date
- Sep 2009
- Posts
- 10
- Rep Power
- 0
The code looks like this now:
Maybe FileNotFoundException should be catched eariler, before the loop.
I added the NumberFormat as you said, and a method I found by google to get the right file extension, and I also changed it back to one loop and now it works pefect!Java Code:import java.awt.Image; import java.io.*; import java.util.*; import javax.imageio.ImageIO; import java.text.*; public class Sortimages { public static void main(String[] args) throws Exception { Scanner scan = new Scanner(System.in); System.out.println("Specify the path where the files are located!"); String imagespath = scan.nextLine(); System.out.println("Specify the path where you want to move the files!"); String newimagespath = scan.nextLine(); System.out.println("Set a maintitle for the files"); String maintitle = scan.nextLine(); NumberFormat formatter = NumberFormat.getInstance(); formatter.setMinimumIntegerDigits(3); formatter.setGroupingUsed(false); File images = new File(imagespath); File[] files = images.listFiles(); try { for (int i = 0; i < files.length; i++) { System.out.println("processing file " + files[i]); Image image = ImageIO.read(files[i]); if (image == null) { System.out.println("FAILED - " + files[i]); } int width = image.getWidth(null); int height = image.getHeight(null); File folder = new File(newimagespath + "\\" + width + "x" + height + "\\"); folder.mkdir(); int inumber = 1; String ext = getFileExtensionName(files[i]); while (inumber < 100) { if (new File(folder, maintitle + " - " + formatter.format(i + inumber) + "." + ext).exists()) { inumber++; } else { break; } } File newfile = new File(folder, maintitle + " - " + formatter.format(i + inumber) + "." + ext); files[i].renameTo(newfile); } } catch (NullPointerException npe) { System.out.println("Caught NullPointerException " + "\nThere is a non graphical file in the folder! Try to move the files to a new folder."); } catch (FileNotFoundException fnfe) { System.out.println("Caught FileNotFoundException " + "The specified folder doesn't exist"); } finally { scan.close(); System.out.close(); } } public static String getFileExtensionName(File f) { if (f.getName().indexOf(".") == -1) { return ""; } else { return f.getName().substring(f.getName().length() - 3, f.getName().length()); } } }
Thank you so much for all your help!
Similar Threads
-
Scaling a JPEG
By ScottVal in forum Advanced JavaReplies: 5Last Post: 03-21-2009, 08:47 PM -
Save image as JPEG
By aartheesrini in forum Java AppletsReplies: 1Last Post: 03-16-2009, 05:56 AM -
how to display uploaded jpeg in jsp(its urgent)
By shaktish in forum JavaServer Pages (JSP) and JSTLReplies: 4Last Post: 02-17-2009, 02:52 PM -
Image Coversion .indd to .jpeg
By vipin.arora@hcl.in in forum AWT / SwingReplies: 4Last Post: 02-12-2009, 07:52 AM -
extracting text from jpeg
By Nicholas Jordan in forum Advanced JavaReplies: 0Last Post: 10-05-2008, 11:40 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks