Results 1 to 12 of 12
  1. #1
    Umi
    Umi is offline Member
    Join Date
    Sep 2009
    Posts
    10
    Rep Power
    0

    Default Help with moving jpeg files

    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);
                
            }
        }
    }
    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.
    Can anyone see what I'm doing wrong?

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default

    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.

  3. #3
    Umi
    Umi is offline Member
    Join Date
    Sep 2009
    Posts
    10
    Rep Power
    0

    Default

    Java Code:
    boolean success = files[i].renameTo(newfile);
                if (!success){
                    System.out.println("RenameTo did not success");
    I added that in the end of the for loop. When I run the file I get the message for every file.
    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.
    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]);
                }
            }
        }
    }
    This works fine, although the last file doesn't move.
    Can you see why? Because I don't see any thing that could be wrong.

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default

    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:
    Java Code:
            for (int i = 0; i < files.length; i++) {
                Image image = JPEGCodec.createJPEGDecoder(new FileInputStream(files[i])).decodeAsBufferedImage();
    ...etc etc...
    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()
    {
        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}
    }

  5. #5
    Umi
    Umi is offline Member
    Join Date
    Sep 2009
    Posts
    10
    Rep Power
    0

    Default

    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:
    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]);
                }
            }
        }
    }
    I'm not sure if it works perfectly now, but all images is moved in any case, so Thanks a lot!

  6. #6
    Umi
    Umi is offline Member
    Join Date
    Sep 2009
    Posts
    10
    Rep Power
    0

    Default

    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:
    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();
        }
    However when running the file I get this error:

    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.

  7. #7
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default

    Quote Originally Posted by Umi View Post
    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.
    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.

    Quote Originally Posted by Umi View Post
    However when running the file I get this error:

    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.
    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.

  8. #8
    Umi
    Umi is offline Member
    Join Date
    Sep 2009
    Posts
    10
    Rep Power
    0

    Default

    Quote Originally Posted by Tolls View Post
    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.
    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.

  9. #9
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default

    OK, taking your code as a start point (I've changed the input stream to a File).

    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();
    }
    That's all you should need. It'll tell you exactly which files it's failing on.
    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).

  10. #10
    Umi
    Umi is offline Member
    Join Date
    Sep 2009
    Posts
    10
    Rep Power
    0

    Default

    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!

    Quote Originally Posted by Tolls View Post
    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.
    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.

  11. #11
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,009
    Rep Power
    20

    Default

    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.

  12. #12
    Umi
    Umi is offline Member
    Join Date
    Sep 2009
    Posts
    10
    Rep Power
    0

    Default

    The code looks like this now:
    Maybe FileNotFoundException should be catched eariler, before the loop.

    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());
            }
        }
    }
    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!
    Thank you so much for all your help!

Similar Threads

  1. Scaling a JPEG
    By ScottVal in forum Advanced Java
    Replies: 5
    Last Post: 03-21-2009, 08:47 PM
  2. Save image as JPEG
    By aartheesrini in forum Java Applets
    Replies: 1
    Last Post: 03-16-2009, 05:56 AM
  3. how to display uploaded jpeg in jsp(its urgent)
    By shaktish in forum JavaServer Pages (JSP) and JSTL
    Replies: 4
    Last Post: 02-17-2009, 02:52 PM
  4. Image Coversion .indd to .jpeg
    By vipin.arora@hcl.in in forum AWT / Swing
    Replies: 4
    Last Post: 02-12-2009, 07:52 AM
  5. extracting text from jpeg
    By Nicholas Jordan in forum Advanced Java
    Replies: 0
    Last Post: 10-05-2008, 11:40 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •