School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!
Welcome to Dream.In.Code
Become an Expert!

Join 340,125 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 4,063 people online right now. Registration is fast and FREE... Join Now!



Mass Thumbnail creator

Mass Thumbnail creator Rate Topic: -----

#1 BetaWar  Icon User is online

  • #include <soul.h>
  • Icon
  • Group: Moderators
  • Posts: 4,945
  • Joined: 07-September 06


Dream Kudos: 1500

Posted 30 April 2009 - 05:27 PM

Okay, so I am working on this as a project (somewhat for school, but not totally). But, I have run into a bit of trouble with Java running out a heap space (which I am not exactly sure of the reason for as I don't know of any memory leaks that the program has (or really can have) and am gc-ing and flushing everything (I think) each time through the loop.

Here is the code:

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class Runner{
	public static JFrame gui;
	public static LinkedList<File> files;
	public static int totalFiles;
	public static int percentage;
	public static void main(String args[]){
		gui = new JFrame();
		percentage = 0;
		totalFiles = 0;
		files = new LinkedList<File>();
		gui.setTitle("Thumbnail Maker v1.0");
		gui.setResizable(false);
		gui.setSize(300, 70);
		gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		
		gui.setVisible(true);
		writeLine("Initializing...", 5, 15);
		File dir = new File("C:/Users/Jamedon/Pictures/da2/");
		getFilesBegin(dir);
		makeThumbs();
	}
	public static void clearScreen(){
		clearBox(0, 0, 300, 300);
	}
	public static void clearBox(int x, int y, int width, int height){
		gui.getContentPane().getGraphics().clearRect(x, y, height, width);
	}
	public static void writeLine(String str, int x, int y){
		gui.getContentPane().getGraphics().drawString(str, x, y);
	}
	public static void makeThumbs(){
		for(int i=1; !files.isEmpty(); i++){
			String op = files.pop().getAbsolutePath();
			clearScreen();
			writeLine(op, 5, 15);
			writeLine("Percentage completed: "+percentage+"%", 5, 30);
			percentage = (int)((((double)i+1)/totalFiles)*100);
			try{
				scale(op, 100, "G:/Documents/Pictures/thumbnails/thumb_"+i+".jpg");
			}
			catch (IOException e){
				clearScreen();
				writeLine("Fatal Error, IO exception.", 5, 15);
				return;
			}
			System.gc();
		}
	}
	public static void scale(String srcFile, int destWidth, String destFile) throws IOException {
		BufferedImage src = ImageIO.read(new File(srcFile));
		AffineTransform at;
		if(src.getWidth() > src.getHeight()){ // scale correctly
			at = AffineTransform.getScaleInstance((double)destWidth/src.getWidth(), (double)destWidth/src.getWidth());
		}
		else{
			at = AffineTransform.getScaleInstance((double)destWidth/src.getHeight(), (double)destWidth/src.getHeight());
		}
		BufferedImage dest = new BufferedImage((int)(at.getScaleX()*src.getWidth()), (int)(at.getScaleY()*src.getHeight()), BufferedImage.TYPE_INT_RGB);
		Graphics2D g = dest.createGraphics();
		g.drawRenderedImage(src, at);
		ImageIO.write(dest, "JPG", new File(destFile));
		g.dispose(); // clean up.
		dest.flush();
		src.flush();
	}
	public static void getFilesBegin(File dir){
		clearScreen();
		writeLine("Loading files from "+dir, 5, 15);
		writeLine("Percentage completed: "+percentage+"%", 5, 30);
		getFiles(dir);
	}
	public static void getFiles(File dir){
		String[] children = dir.list();
	    if(children == null){
	    	return;
	    }
	    for(int i=0; i<children.length; i++){
	       	getFiles(new File(dir.getAbsolutePath()+children[i]));
	       	String filename = children[i];
	       	try{
	       		String ext = filename.split("\\.")[1];
	       		if(isImageExtension(ext)){
	       			files.push(new File(dir.getAbsolutePath()+"\\"+filename));
	       			totalFiles++;
	       		}
	       	}
	       	catch(Exception e){
	       		getFiles(new File(dir.getAbsolutePath()+"\\"+filename+"\\"));
	       	}
	    }
	    System.gc();
	}
	public static boolean isImageExtension(String ext){
		return ext.toLowerCase().matches("(png|bmp|jpeg|jpg|gif|tiff)");
	}
}


public class LinkedList<E>{
	private Node<E> head;
	int length;
	public LinkedList(){
		head = new Node<E>(null, head, head);
		head.setPrev(head);
		length = 0;
	}
	public E pop(){
		E temp = head.getNext().getItem();
		head.getNext().getNext().setPrev(head);
		head.setNext(head.getNext().getNext());
		length--;
		System.gc();
		return temp;
	}
	public void push(E item){
		Node<E> newNode = new Node<E>(item, head, head.getPrev());
		head.getPrev().setNext(newNode);
		head.setPrev(newNode);
		length++;
	}
	public boolean isEmpty(){
		return length==0;
	}
	public String toString(){
		String ret = new String("Length: "+length+"\n");
		Node<E> cNode = head.getNext();
		for(int i=0; cNode!=head; i++, cNode = cNode.getNext()){
			ret += "Item: "+i+", contains: "+cNode.getItem()+"\n";
		}
		return ret;
	}
}


The above class is for school. I am have stripped out most of the functions it orignally had to make it easier on the eyes (and act more like a queue).

public class Node<E>{
	private E payload;
	private Node<E> next;
	private Node<E> prev;
	public Node(E item, Node<E> n, Node<E> p){
		payload = item;
		next = n;
		prev = p;
	}
	public E getItem(){
		return payload;
	}
	public void setNext(Node<E> n){
		next = n;
	}
	public void setPrev(Node<E> p){
		prev = p;
	}
	public Node<E> getNext(){
		return next;
	}
	public Node<E> getPrev(){
		return prev;
	}
}


At this point I am having it go through about 50 images, which it gets to 61% complete, and then I get the following error:

Quote

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferByte.<init>(Unknown Source)
at java.awt.image.ComponentSampleModel.createDataBuffer(Unknown Source)
at java.awt.image.Raster.createWritableRaster(Unknown Source)
at javax.imageio.ImageTypeSpecifier.createBufferedImage(Unknown Source)
at javax.imageio.ImageReader.getDestination(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at Runner.scale(Runner.java:59)
at Runner.makeThumbs(Runner.java:48)
at Runner.main(Runner.java:28)


Just wondering if there is anything obvious that I could do to improve preformance or at least get the program to finish (without limiting the number of images it can have in the linked list at one time).

Any help would be appreciated.
Was This Post Helpful? 0
  • +
  • -


#2 pbl  Icon User is offline

  • Java Lover
  • Icon
  • Group: Mentors
  • Posts: 11,168
  • Joined: 06-March 08


Dream Kudos: 475

Posted 30 April 2009 - 06:15 PM

For a reason I don't know I cannot cut & paste your code to test it... there is no linefeed

You are in an infinite loop... I suspect your pop() method not retrieving the node from the LinkedList

also replace that:
public static void makeThumbs() {				
	 for(int i=1; !files.isEmpty(); i++){


by
public static void makeThumbs() {  
   int i = 0;
   while(!files.isEmpty()) {
	  i++;
	  printf("Processing file " + i + " out of " + files.length + " left");



You can remove all your System.gc();

This post has been edited by pbl: 30 April 2009 - 06:32 PM

Was This Post Helpful? 1
  • +
  • -

#3 BetaWar  Icon User is online

  • #include <soul.h>
  • Icon
  • Group: Moderators
  • Posts: 4,945
  • Joined: 07-September 06


Dream Kudos: 1500

Posted 01 May 2009 - 09:23 AM

Hm, I don't think there is an infinite loop problem. When I change the scale() function call out with System.out.println(op); it outputs all the file paths in the linked list (and uses the pop() function to get them).

I have attached the project source (zipped):
Attached File  src.zip (2.18K)
Number of downloads: 9

I have removed all gc() calls as well.
Was This Post Helpful? 0
  • +
  • -

#4 BetaWar  Icon User is online

  • #include <soul.h>
  • Icon
  • Group: Moderators
  • Posts: 4,945
  • Joined: 07-September 06


Dream Kudos: 1500

Posted 03 May 2009 - 07:35 PM

- bump -
Was This Post Helpful? 0
  • +
  • -

#5 pbl  Icon User is offline

  • Java Lover
  • Icon
  • Group: Mentors
  • Posts: 11,168
  • Joined: 06-March 08


Dream Kudos: 475

Posted 03 May 2009 - 07:42 PM

View PostBetaWar, on 3 May, 2009 - 07:35 PM, said:

- bump -

sorry BetaWar can't still cut & paste your code to test it
must be Linux to Windows issue... but this does not happens often
what did you do wrong ? :D
Was This Post Helpful? 1
  • +
  • -

#6 BetaWar  Icon User is online

  • #include <soul.h>
  • Icon
  • Group: Moderators
  • Posts: 4,945
  • Joined: 07-September 06


Dream Kudos: 1500

Posted 04 May 2009 - 09:14 AM

I don't know, I don't believe any of the calls I am using are Windows only... It is using the standard java libraries, so I have no idea. Does linux not allow swing?
Was This Post Helpful? 0
  • +
  • -

#7 pbl  Icon User is offline

  • Java Lover
  • Icon
  • Group: Mentors
  • Posts: 11,168
  • Joined: 06-March 08


Dream Kudos: 475

Posted 04 May 2009 - 02:41 PM

View PostBetaWar, on 4 May, 2009 - 09:14 AM, said:

I don't know, I don't believe any of the calls I am using are Windows only... It is using the standard java libraries, so I have no idea. Does linux not allow swing?

:D

Did you tried my System.out.println() ? ... sorry I posted "printf" was probably just out of the office
Was This Post Helpful? 0
  • +
  • -

#8 BetaWar  Icon User is online

  • #include <soul.h>
  • Icon
  • Group: Moderators
  • Posts: 4,945
  • Joined: 07-September 06


Dream Kudos: 1500

Posted 05 May 2009 - 04:38 AM

Ya, I tried the println. It never outputs the same file twice (which is like i should, as it is a queue).
Was This Post Helpful? 0
  • +
  • -

#9 pbl  Icon User is offline

  • Java Lover
  • Icon
  • Group: Mentors
  • Posts: 11,168
  • Joined: 06-March 08


Dream Kudos: 475

Posted 05 May 2009 - 03:37 PM

View PostBetaWar, on 5 May, 2009 - 04:38 AM, said:

Ya, I tried the println. It never outputs the same file twice (which is like i should, as it is a queue).

And the size of the queue decreses ?
Was This Post Helpful? 0
  • +
  • -

#10 BetaWar  Icon User is online

  • #include <soul.h>
  • Icon
  • Group: Moderators
  • Posts: 4,945
  • Joined: 07-September 06


Dream Kudos: 1500

Posted 05 May 2009 - 07:41 PM

Yes. At this point it looks like it has problems with images over 5 MB, so if there is an easy way to check file size (accurately) and compare it, I have tried the getTotalSize() method that Files have, but that doesn't seem to work correctly, not sure why.
Was This Post Helpful? 0
  • +
  • -



Fast Reply

  

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users



Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month