Skip to main content

creating a BufferedImage and efficient way of reusing.....

8 replies [Last post]
cohodetector
Offline
Joined: 2007-07-12
Points: 0

Hello,

I have a method that creates a BufferedImage from a byte[]. It is a gray-scale image, and each pixels in the image is represent by a single byte range from 0 to 255. here is the method:

public BufferedImage produceRenderedImage(byte[] dataBuffer, int width, int height)
{
DataBuffer dBuffer = new DataBufferByte(dataBuffer, width * height);
WritableRaster wr = Raster.createInterleavedRaster(dBuffer,width,height,width,1,new int[]{0},null);
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorModel cm = new ComponentColorModel(cs,false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
BufferedImage bi = new BufferedImage(cm, wr, false, null);

return bi;
}

Now this method got call several time in the while loop where the while loop get the byte[] array of the raw image from the server. My question is that is there a way that i can optimize this so that it uses less "new" operator because it allocates space. the only changes in the above method during the while loop is the byte[] dataBuffer. of course the WritableRaster change as well since it uses byte[] dataBuffer to create the WritableRaster.

Thanks

Francis

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
trembovetski
Offline
Joined: 2003-12-31
Points: 0

Your dataBuffer array will by far be the biggest problem, the rest of the objects don't take much time - they're just wrappers allowing access to the data array.

You might want to cycle between a couple of data arrays or something instead of creating a new one every time.

Dmitri

Dmitri Trembovetski

> the rest of the objects don't take much time

And by "time" I mean "space". They're the same thing anyway!

Dmitri

java2d@JAVADESKTOP.ORG wrote:
> Your dataBuffer array will by far be the biggest problem, the rest of the objects don't take much time - they're just wrappers allowing access to the data array.
>
> You might want to cycle between a couple of data arrays or something instead of creating a new one every time.
>
> Dmitri
> [Message sent by forum member 'trembovetski' (trembovetski)]
>
> http://forums.java.net/jive/thread.jspa?messageID=288924
>
> ===========================================================================
> To unsubscribe, send email to listserv@java.sun.com and include in the body
> of the message "signoff JAVA2D-INTEREST". For general help, send email to
> listserv@java.sun.com and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

cohodetector
Offline
Joined: 2007-07-12
Points: 0

What do u mean by cycling two data array? and how would i get started on that? is there a some sort of method on the dataBuffer that i can reset my byte[] array?

thank you

Francis

trembovetski
Offline
Joined: 2003-12-31
Points: 0

I don't have enough information on what exactly you're doing to advise you on the implementation, but I thought that if you have something that generates a new array of pixels on every frame (may be from a different thread or something), may be you could have two arrays - one you currently render from, and another which is updated, then you'd swap them around after every update. Just a thought.

But ideally, you'd just have one array (and a DataBuffer) which you'd load with new data, no need to create new one ever time (unless the size of the array changes).

Dmitri

cohodetector
Offline
Joined: 2007-07-12
Points: 0

First, i am extracting images from the video stream by taking a snap shot of each images from the video, and then I extracted the pixels data from those images using pixelGrabbers. This return a byte[] array of pixels information of the image. then i create BufferedImage using the method i posted above, but the way that i have written can cause out of heap memory error because i am declaring "new" everytime i got a new dataBuffer. the dimension of the byte[] dataBuffer is the same; the only change is the pixel info. Here is some part of my program:

public class ExtractImage{
//start video stream
//then take a snap shot of video at every 5 seconds.
//then extract the pixel info from the snap shot image using pixelsGrabber, and
//then put that data in the byte[] dataBuffer array.
//After that produce BufferedImage or RenderedImage by calling this //produceRenderedImage method.

public BufferedImage produceRenderedImage(byte[] dataBuffer, int width, int height)
{
DataBuffer dBuffer = new DataBufferByte(dataBuffer, width * height);
WritableRaster wr = Raster.createInterleavedRaster(dBuffer,width,height,width,1,new int[]{0},null);
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorModel cm = new ComponentColorModel(cs,false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
BufferedImage bi = new BufferedImage(cm, wr, false, null);

return bi;
}
}
thanks for all your help. i really appreciated it.

Francis

Jim Graham

How are you taking the snap shot? How do you receive that snapshot into
Java? By loading it as an image, or are you using the built-in robot
facilities to do the snapshot?

If you are using robot, then the image will already be a BufferedImage
so you don't need to convert it. If you are loading a snapshot stored
as a file, then you can load the image using ImageI/O instead of
Toolkit/Component.getImage() and get a BufferedImage that way...

...jim

java2d@JAVADESKTOP.ORG wrote:
> First, i am extracting images from the video stream by taking a snap shot of each images from the video, and then I extracted the pixels data from those images using pixelGrabbers. This return a byte[] array of pixels information of the image. then i create BufferedImage using the method i posted above, but the way that i have written can cause out of heap memory error because i am declaring "new" everytime i got a new dataBuffer. the dimension of the byte[] dataBuffer is the same; the only change is the pixel info. Here is some part of my program:
>
> public class ExtractImage{
> //start video stream
> //then take a snap shot of video at every 5 seconds.
> //then extract the pixel info from the snap shot image using pixelsGrabber, and
> //then put that data in the byte[] dataBuffer array.
> //After that produce BufferedImage or RenderedImage by calling this //produceRenderedImage method.
>
> public BufferedImage produceRenderedImage(byte[] dataBuffer, int width, int height)
> {
> DataBuffer dBuffer = new DataBufferByte(dataBuffer, width * height);
> WritableRaster wr = Raster.createInterleavedRaster(dBuffer,width,height,width,1,new int[]{0},null);
> ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
> ColorModel cm = new ComponentColorModel(cs,false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
> BufferedImage bi = new BufferedImage(cm, wr, false, null);
>
> return bi;
> }
> }
> thanks for all your help. i really appreciated it.
>
> Francis
> [Message sent by forum member 'cohodetector' (cohodetector)]
>
> http://forums.java.net/jive/thread.jspa?messageID=289444
>
> ===========================================================================
> To unsubscribe, send email to listserv@java.sun.com and include in the body
> of the message "signoff JAVA2D-INTEREST". For general help, send email to
> listserv@java.sun.com and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

cohodetector
Offline
Joined: 2007-07-12
Points: 0

Hello,

I am using JMF (Java Media Framework) to video stream, and then i am taking a snap shot of that video stream at every 5 seconds. there is a class called FrameGrabber in JMF that grabs a frame and return that frame as java.awt.Image. Then i took that image and deinterlace it. Deinterlacing is separating the odd line and eve line from that image. Here is more expalanation of deinterlacing : http://en.wikipedia.org/wiki/Deinterlacing
The separation is done by extracting the pixels from the Image using pixels grabber, which returns the int[] array, but i converted to a byte[] array to save memory because i am video streaming the gray-scale and I am calling this method several time in the while loop. Then after that i called this method that i posted in the previous message, again this is also called several time in the while loop:

public BufferedImage produceRenderedImage(byte[] dataBuffer, int width, int height)
{
DataBuffer dBuffer = new DataBufferByte(dataBuffer, width * height);
WritableRaster wr = Raster.createInterleavedRaster(dBuffer,width,height,width,1,new int[]{0},null);
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorModel cm = new ComponentColorModel(cs,false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
BufferedImage bi = new BufferedImage(cm, wr, false, null);

return bi;
}

there are two lines of code i am worry the most, which might cause OUT OF HEAP MEMORY issue because in my method above i called the
>> new DataBufferByte(dataBuffer, width * height)
>> new BufferedImage(cm,wr,false,null).

The other two lines can be put outside of the method becasue they don't change through out during the several called in while loop. they are:
>>ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
>>ColorModel cm = new ComponentColorModel(cs,false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);

The only thing change in the above method is the dataBuffer, the byte[] data changes in every loop from the images from the video. The dimension is the same. Is there a way to reset the dataBuffer without the recalling new DataBufferByte(dataBuffer, width * height)? i saw a data buffer that reset the int (setInt() )in the DataBuffer class, but not a setByte method?

thanks

Francis

cohodetector
Offline
Joined: 2007-07-12
Points: 0

>>The only thing change in the above method is the dataBuffer, the byte[] data changes in every loop from the images from the video. The dimension is the same. Is there a way to reset the dataBuffer without the recalling new DataBufferByte(dataBuffer, width * height)? i saw a data buffer that reset the int (setInt() )in the DataBuffer class, but not a setByte method?

well, actually it was in the WritableRaster class.it is called
setPixel(int x, int y, int[] iArray)

http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/WritableRaster.html#setPixel(int,%20int,%20int[])

i don't see a set byte method.

thanks

Francis