i recently needed to load images really really fast and access their pixel data.
so just in case anyone ever needs i'll post it here...
this allows you to load java bufferedimages, not processing's PImage.
most likely this will interrest you if you need to load lots of images and access their pixel data directly.
so far i've tested it on mac and windows with sun jvms, this might break if you use another vendors jvm.
* This is a bit of a hack and might change depending on which jdk you use!
public static BufferedImage loadImageCrazyFast( URL src ){
Image im = Toolkit.getDefaultToolkit().createImage( src );
so ultimately you'd use it like this:
BufferedImage img = loadImageCrazyFast( new File( "test.jpg" ).toURI().toURL() );
int pixels[] = loadPixelsCrazyFast( img );
img.flush(); // call this or you'll have memory leaks!
should be a good starting point if you ever need fast image loading...
none, they're just rebranding everything from sun to oracle as an effect of the acquisition.
i was referring to exotic jvms like versions of openjdk, kaffee, blackdown. this problem would only occur on linux systems were the jvm market is more diverse. on windows and macos afaik everyone uses the default implementation.
the problem originates from the use of the "getBufferedImage" function, which is not necessarily implemented so you cannot rely on it 100% (even if it's unlikely, but this might even change in future sun/oracle implementations).
Hey Hansi, thanks for the post.. always looking for new ways to speed up my data loads (particularly the tip on flushing the BufferedImage). The code may be quicker than a PImage load, but seems a lot slower than using ImageIO.read(URL);
I'm actually trying to improve the performance of my Texture loads for OpenGL. My code below is the fastest way I've found so far (at least for texture loading), but wanted to try the direct OpenGL methods when I get a chance and figure it out.
Your code timed at 1419.0ms
The code below timed at 522.0ms
http://stackoverflow.com/questions/1927419/loading-pngs-into-opengl-performance-issues-java-jogl-much-slower-than-c-t
PixelGrabber grabber =
new PixelGrabber(image, 0, 0, -1, -1, false);
if (grabber.grabPixels()) {
int w = grabber.getWidth();
int h = grabber.getHeight();
retval = createImage(w,h,ARGB);
if (isGreyscaleImage(grabber)) {
byte[] datax = (byte[]) grabber.getPixels();
arraycopy(datax,retval.pixels);
// Process greyscale image ...
}
else {
data = (int[]) grabber.getPixels();
arraycopy(data,retval.pixels);
//arraycopy(data,pixels);
// Process Color image
public static final boolean isGreyscaleImage(PixelGrabber pg) {
return pg.getPixels() instanceof byte[];
}
Nice!
I'll try to put something together in a quick sketch.
Toolkit.getDefaultToolkit().getImage(inFile); does read faster on JPG images, not sure about my PNG, will have to test, but it takes longer to load them into my TextureIO.newTexture() leaving the results about the same. Didn't try all the pixel grabbing, since I"m not trying to get it into a PImage, but a Texture2D. So now I'll be trying to figure out how to get that Image Toolkit trick, which I turned into a BufferedImage, into a Texture2D. I think I've worked out the another way that's a lot faster for building the TextureIO if I can quickly build the glTexImage2D.
I find that it only works with local .png files. (i.e. the files have to be on your hard drive and they have to be .png files)
But it almost twice as fast as loadImage();
Would be great if we could expand it's use to include jpg. :-) I guess at the least.. it would be easy to add if the string ends with ".png" do this, if not pass it to loadImage(). This is something I'm excited about... increasing my load performance would be great. When you say local.. I expect the inner class calls would also work.. getClass().getClassLoader().getResource(file);
Phillo, that did work, along with adding in a default for dataPath(), like loadImage does. Here is my revised version.
UPDATE: Better version below
new java.awt.image.PixelGrabber(image, 0, 0, -1, -1, false);
if (grabber.grabPixels()) {
int w = grabber.getWidth();
int h = grabber.getHeight();
if (inFile.toLowerCase().endsWith(".jpg") || inFile.toLowerCase().endsWith(".jpeg") ) {
retval = createImage(w, h, RGB);
else {
retval = createImage(w, h, ARGB);
if (grabber.getPixels() instanceof byte[]) {
byte[] datax = (byte[]) grabber.getPixels();
arraycopy(datax, retval.pixels);
// Process greyscale image ...
else {
data = (int[]) grabber.getPixels();
arraycopy(data, retval.pixels);
//arraycopy(data,pixels);
// Process Color image
catch (InterruptedException e1) {
e1.printStackTrace();
return retval;
} else {
return null;
Here is a version that I tested to work with an applet, though it's not as fast Owaunandrew's code, it's still twice as fast as the normal loadImage() and it works with jpg and png. If the image is not a jpg, png or encounters problems, it drops back to the normal loadImage(), so it could be used as a drop in replacement for loadImage() to gain added performance on these file types.
Normal loadImage(): avg 80ms
Owaunandrew's code: avg 35ms
Modified below using loadBytes(): avg 40ms
PImage loadImagex(String inFile) {
if (inFile.toLowerCase().endsWith(".jpg") || inFile.toLowerCase().endsWith(".jpeg") || inFile.toLowerCase().endsWith(".png")) {
new java.awt.image.PixelGrabber(image, 0, 0, -1, -1, false);
if (grabber.grabPixels()) {
int w = grabber.getWidth();
int h = grabber.getHeight();
if (inFile.toLowerCase().endsWith(".jpg") || inFile.toLowerCase().endsWith(".jpeg") ) {
retval = createImage(w, h, RGB);
else {
retval = createImage(w, h, ARGB);
if (grabber.getPixels() instanceof byte[]) {
// Process greyscale image ...
byte[] datax = (byte[]) grabber.getPixels();
arraycopy(datax, retval.pixels);
else {
// Process Color image
data = (int[]) grabber.getPixels();
arraycopy(data, retval.pixels);
catch (InterruptedException e1) {
System.err.println("Problem loading loadImagex, defaulting to loadImage(). Error: " + e1);
return loadImage(inFile);
if (retval != null) {
return retval;
return loadImage(inFile);
return loadImages(inFile);
return loadImage(inFile);
Textures... I'm still trying to work out the best method for loading them. The code I posted in my first post in this thread is the fastest thus far overall, but I had mix results with it working. When I say overall, I break the Texture time into two parts: Loading the file, applying the file to a texture. I break these in two parts as the first can be done on a separate thread, where the second must be done on the main thread where it has access to the GL context. The code above is very fast on loading the file, but average on applying the texture, the sum being the fastest. The code I will post below is fast on applying the texture but average on the load. So I'm hoping to find a good match of fast load and fast apply, but at the moment applying the texture with speed is more important to me as it actually halts the pipeline and delays the draw.
So I'm using the below method, but if anyone knows how to very quickly load data into TextureData or directly into a Texture2D, that would probably be the best method. The second part at the bottom is what really boosts the speed of applying the texture over the common method of directly loading to the TextureIO.newTexture();
First part
import com.sun.opengl.util.texture.*;
import javax.imageio.ImageIO;
import javax.media.opengl.GL;
Texture mytexture;
void setup() {
TextureData td;
try { //this can be done in a separate thread
// BufferedImage, mipmap or InputStream, mipmap, extension
// BufferedImage using ReadIO worked best in my tests,
// but the InputStream createInput can be used directly by adding the "png" extension