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.
IndexProgramming Questions & HelpPrograms › Can't create PImage from byte[]
Page Index Toggle Pages: 1
Can't create PImage from byte[] (Read 1662 times)
Can't create PImage from byte[]
Feb 13th, 2009, 6:39pm
 
Dear Processing Community

I'm trying to load images from a Sqlite-Database.
As I'm facing LOTS of images I use soft references for the images that need to be shown...
Getting the image looks like this:

Code:

public PImage getImage(){
if(imageData == null || img != null || img.get() == null){
String sql = "select image_data from mood where id=" + id;
imageData = ActiveRecordManager.executeBinaryQuery(sql, "image_data");
}

try {
if(img == null || img.get() == null){
img = new SoftReference<PImage>(new PImage(ImageIO.read(new ByteArrayInputStream(imageData))));
}
imageData = null;
return img.get();
} catch (IOException e) {
e.printStackTrace();
}
finally{
ActiveRecordManager.setAutoCommit(true);
}
return null;
}


I am however getting a weird exception:
Code:

Setting pragma flags:
Exception in thread "Animation Thread" java.lang.ClassCastException: [I cannot be cast to [B

at sun.awt.image.ByteInterleavedRaster.getDataElements(ByteInterleavedRaster.java:351)

at processing.core.PImage.<init>(PImage.java:182)

at ch.mood.domain.MoodImage.getImage(MoodImage.java:110)

at ch.mood.gfx.AnimatedImage.draw(AnimatedImage.java:42)

at ch.mood.frames.MouseClickProcessingFrame.draw(MouseClickProcessingFrame.java:45)

at processing.core.PApplet.handleDraw(PApplet.java:1406)

at processing.core.PApplet.run(PApplet.java:1311)

at java.lang.Thread.run(Thread.java:637)


What gives? The byte[] is loaded just fine from the database(I checked using the debugger) and in an earlier version of the code I used Java2D and displayed BufferedImages, which also worked fine. What's wrong with the code?
Re: Can't create PImage from byte[]
Reply #1 - Feb 13th, 2009, 10:21pm
 
Though I haven't looked at the Processing source code, I don't think there is a constructor of PImage that takes a byte[].

You could make a new empty PImage and copy to it's pixels[] from your source array.

Edit: copy, not assign
Re: Can't create PImage from byte[]
Reply #2 - Feb 14th, 2009, 12:53pm
 
I'm actually using the constructor for a PImage that takes a Image, which BufferedImage is a Subtype of, and that's what ImageIO.read() returns...
Still there's a class cast exception.
Re: Can't create PImage from byte[]
Reply #3 - Feb 15th, 2009, 6:13am
 
If ImageIO.read(new ByteArrayInputStream(imageData))
ruturns a BufferedImage, you may have to cast it to just an Image.

A BufferedImage is an Image, but Java is kinda picky that way.
Re: Can't create PImage from byte[]
Reply #4 - Feb 16th, 2009, 10:00am
 
That can't be, I have the Source-Code of PImage(Image) and it handles BufferedImages by checking the type of the image passed in.
I tried adding the cast nontheless, but it still doesn't work.

However, the exception occurs in the call to: WritableRaster.getDataElements()...
Re: Can't create PImage from byte[]
Reply #5 - Feb 17th, 2009, 9:33am
 
I've been playing around with it and got this to work with a BufferedImage:

Code:

Graphics2D g2 = ((PGraphicsJava2D)g).g2;

g2.drawImage(bi, null, 0, 0);


Edit: Oh, and this uses a PGraphics object rather than PImage.
That assumes that the PGraphics object(g) is the same size as the BufferedImage(bi).
If that doesn't do what you need, I can play some more :]
Re: Can't create PImage from byte[]
Reply #6 - Feb 17th, 2009, 9:50am
 
I actually hoped I could stay in the processing domain and not go back to Java2D for this. I can't be something no one ever does. BufferedImage is such a common class. Loading images from disk is such a common case.
Loading images from a database (or any other source where you get a byte[], aamof) should not be so uncommon. There has to be a nice, clean way to do this.

In the mean time, thanks for the answer I will try it out today, when I get time to work on my processing project, as there's lots of other code that needs tending too Cheesy
Re: Can't create PImage from byte[]
Reply #7 - Feb 17th, 2009, 10:03am
 
BufferedImage is already Java2D, Processing and Java are solidly tied... Smiley

Beside, I would try and split your complex sentence in three parts (using intermediary variables). Perhaps the exception isn't in the part you thing...
Re: Can't create PImage from byte[]
Reply #8 - Feb 17th, 2009, 10:30am
 
What I had in mind only used Java2D to load the image:

Code:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import processing.core.*;

public class pap extends PApplet {

BufferedImage bi;
PGraphics work;

public void setup() {
size(640, 480);

bi = new BufferedImage (640, 480, BufferedImage.TYPE_INT_RGB);

//You can load bi from your database
//or paint into it with this
Graphics2D gbi = bi.createGraphics();
gbi.setColor(new Color(255,255,255));
gbi.fillRect(20, 20, 50, 50);



work = createGraphics(640,480,JAVA2D);

Graphics2D gg = ((PGraphicsJava2D)work).g2;

gg.drawImage(bi, null, 0, 0);

frameRate(30);
}


public void draw() {
image(work.get(),0,0);
}

static public void main(String args[]) {
PApplet.main(new String[] {"pap" });
}

}
Re: Can't create PImage from byte[]
Reply #9 - Feb 17th, 2009, 1:38pm
 
PhiLho  wrote on Feb 17th, 2009, 10:03am:
BufferedImage is already Java2D, Processing and Java are solidly tied... Smiley

Beside, I would try and split your complex sentence in three parts (using intermediary variables). Perhaps the exception isn't in the part you thing...


That was pretty clear to me.
Which complex sentence do you mean The one with the ByteArrayInputStream That's practically an idiom Cheesy

Thanks for the pointers, will try later.
Re: Can't create PImage from byte[]
Reply #10 - Feb 19th, 2009, 11:34am
 
Ok, so here's what I found after going through both the PApplet and PImage classes. The way to get this to work without any additional drawing involved (which I don't want):

Code:

byte[] imgBytes = loadBytes("../img/bird.jpg");
Image awtImage = Toolkit.getDefaultToolkit().createImage(imgBytes);
PImage img = loadImageMT(awtImage);


This can successfully be used to create a PImage from a byte[]. I don't know if it works for pngs as well, or only for jpegs. One would have to find out. I don't especially like the call to Toolkit.... but if that's what it takes...

If this is can be confirmed as being the nicest and fastest way (the second being way more important), then this should maybe find it's way into the PImage/PApplet class:

Something like

Code:

public PImage loadImage(byte[])


would rock.
Page Index Toggle Pages: 1