We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexSuggestions & BugsWebsite,  Documentation,  Book Bugs › Fry: Visualizing Data: Chapter 9: Asynchronous Img
Page Index Toggle Pages: 1
Fry: Visualizing Data: Chapter 9: Asynchronous Img (Read 3719 times)
Fry: Visualizing Data: Chapter 9: Asynchronous Img
Mar 28th, 2008, 9:42pm
 
In Chapter 9 of Visualizing Data Fry supplies a script for Asynchronous Image Downloads, available at http://benfry.com/writing/acquire/ImageLoader.java

While I know next to no Java, I believe the following are typos as they produce errors.  The "I" in "PImage" needs to be capitalized:

images = new Pimage[100];     -->     images = new PImage[100];
.
.
.
images = (Pimage[]) expand(images);    -->    images = (PImage[])expand(images)

even when these typos are fixed, the script still doesn't compile as expand() produces an error.

even when the two expand() lines are commented out I still can't get the script to load an image asynchronously.  

has anybody else gotten this script to work?

------
Processing 0135

Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #1 - Mar 28th, 2008, 11:39pm
 
I should clarify.  I've gotten the script to work, but not running as an applet.  If anyone can help with that i'd be much obliged.  When I run it as an applet all i get is a white box (regardless of what i set the background color to).

Here's a simplified version of the code:

-----------------------
the main sketch
-----------------------
Quote:


import processing.opengl.*;

ImageLoader loader;
PImage[] imageList;
int imageCount  =  1;
String path;

void setup()  {
 size(800, 600, OPENGL);

 loader  =  new ImageLoader(this);
 imageList  =  new PImage[imageCount];
path="/absolute/path/to/image.jpg"; //image can reside inside or outside the data folder
 imageList[0]  =  loader.addFile(path);
 loader.finish();
}


void draw()  {
background(255);

if(loader.isFinished())  {
 image(imageList[0],0,0);
}else{
 println("loaderNOTDone");
}

}








----------------------
ImageLoader.java
----------------------
Quote:


import java.awt.*;
import java.awt.image.*;
import java.net.URL;
import processing.core.*;


public class ImageLoader {
 PApplet parent;
 MediaTracker tracker;
 PImage[] images;
 Image[] awtImages;
 int count;
 boolean finished;

 public ImageLoader(PApplet parent) {
   this.parent = parent;
   tracker = new MediaTracker(parent);
   // Start with 100 possible elements and expand as necessary later
   images = new PImage[100];
   awtImages = new Image[100];
 }

 // This method loads images from the Internet, and can be substituted
 // for addFile when testing is finished and the application is deployed.
 public PImage addURL(String url) {
   try {
     return add(Toolkit.getDefaultToolkit().getImage(new URL(url)));
   }
   catch (Exception e) {
     e.printStackTrace();
   }
   return null;
 }

 public PImage addFile(String path) {

   return add(Toolkit.getDefaultToolkit().getImage(path));
 }

 protected PImage add(Image img) {  
   try {
     if (images.length == count) {
       // Expand the image arrays for more than 100 elements
       //images = (PImage[]) expand(images);
       //awtImages = (Image[]) expand(awtImages);
     }
     awtImages[count] = img;
     tracker.addImage(img, count);
     
     images[count] = new PImage();
   }
   catch (Exception e) {
     e.printStackTrace();
   }
   return images[count++];
 }

 public boolean isFinished() {
   if (finished) {
     return true;
   }
   if (tracker.checkAll()) {
     finish();
     return true;
   }
   return false;
 }

 public void finish() {
   try {
     tracker.waitForAll();
   }
   catch (InterruptedException e) {
   }

   for (int i = 0; i < count; i++) {
     if (!tracker.isErrorID(i)) {
       Image img = awtImages[i];
       PImage temp = new PImage(img);
       // Replace the image data without changing the PImage object reference
       images[i].width = temp.width;
       images[i].height = temp.height;
       images[i].format = temp.format;
       images[i].pixels = temp.pixels;
     }
   }
   finished = true;
 }
}




Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #2 - Mar 29th, 2008, 12:34am
 
okay, well i guess i answered my own question.  if running the code through an applet you have to use:

Quote:



path  =  "http://localhost/path/to/image.jpg";
imageList[0]  =  loader.addURL(path);


 



. . . forgot about those applet restrictions (no accessing local files).

anyway, there are still the bugs i mentioned in my first post that need to be corrected.
Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #3 - Apr 5th, 2008, 2:42am
 
sorry to miss this one.. i was out sick for a week and didn't get a chance to respond.

i ran across these problems the other day (just before getting sick, actually) while using the ImageLoader code for another project. the capitalization is a result of NeoOffice being a little too helpful with the "two initial caps".

the other stuff is a little tricky to handle in a way that handles the data folder properly, etc. so i haven't re-posted the new version yet. i'll write something up about it on the book site sometime (very) soon to get it all straightened out. sorry for the trouble!
Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #4 - Aug 6th, 2008, 7:14am
 
any updates on this?
Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #5 - Aug 7th, 2008, 11:30am
 
Eric F. wrote on Aug 6th, 2008, 7:14am:
any updates on this

On what The issue seems to be cleared. Although the code on the site seems not updated yet.
Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #6 - Aug 8th, 2008, 1:32am
 
right, the code and "writing something about it on the book site"
Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #7 - Aug 9th, 2008, 5:10pm
 
Apologies for not getting something up sooner. It's a surprisingly tricky problem, but I've found a good solution and am now baking it into release 0144 since it's something that's used so often.

Until I post release 0144 (or for those using earlier releases), add the following method to your sketch:

Quote:

PImage loadImageAsync(String filename) {
 PImage vessel = createImage(0, 0, ARGB);
 AsyncImageLoader ail = new AsyncImageLoader(this, filename, vessel);
 ail.start();
 return vessel;
}


Next, create a new tab titled "AsyncImageLoader.java". And use this code:

Quote:


import processing.core.*;

public class AsyncImageLoader extends Thread {
 static int loaderMax = 4;
 static int loaderCount;

 PApplet parent;
 String filename;
 PImage vessel;
 
 public AsyncImageLoader(PApplet parent, String filename, PImage vessel) {
   this.parent = parent;
   this.filename = filename;
   this.vessel = vessel;
 }

 public void run() {
   while (loaderCount == loaderMax) {
     try {
       Thread.sleep(10);
     } catch (InterruptedException e) { }
   }
   loaderCount++;
   
   PImage actual = parent.loadImage(filename);
   if (actual == null) {
     vessel.width = -1;
     vessel.height = -1;

   } else {
     vessel.width = actual.width;
     vessel.height = actual.height;
     vessel.format = actual.format;
     vessel.pixels = actual.pixels;
   }
   loaderCount--;
 }
}


Now, when loading images, simply use loadImageAsync() instead of loadImage(). For instance:

Quote:

PImage bigImage;

void setup() {
 bigImage = loadImageAsync("something.jpg");
}

void draw() {
 if (bigImage.width == 0) {
   // image is not yet loaded
 } else if (bigImage.width == -1) {
   // this means an error occurred during image loading
 } else {
   // image is ready to go, draw it
   image(bigImage, 0, 0);
 }
}


For 0144, I've also improved handling of OutOfMemoryErrors since that's so common with image loading. This will fix an increasingly common problem (especially on Mac OS X) that makes it look like an image that didn't load properly has halted the sketch.

(edit) It should also be noted that asynchronous image loading (particularly when downloading from a server) drastically improves performance. In my case it was a 2-3x speedup when downloading 20 JPEG files that were ~3 MB apiece.
Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #8 - Oct 21st, 2008, 5:10pm
 
Does this absolute path work for loading txt files for data parsing as well? I want to be able to export the processing applet and update the images and text data files without going back into processing.
Thanks
Re: Fry: Visualizing Data: Chapter 9: Asynchronous
Reply #9 - Oct 21st, 2008, 7:05pm
 
Yes, all the Processing I/O functions that take a String value support either an absolute path, or a location in the data folder.
Page Index Toggle Pages: 1