displaying JPEG image from array of byte

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

displaying JPEG image from array of byte

Andrew-98
I have a jpeg image as an array of bytes. How can I display and save to it
by a particular name in ImageJ without writing the  image out to a file?
.May someone explain in details.
Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: displaying JPEG image from array of byte

Andy Gotz-2
Hi,

I asked the same question a few days ago. Wayne gave me the answer :

Something like this should work:

  Image img = Toolkit.getDefaultToolkit().createImage(bytes);
  new ImagePlus("title", img).show();

-wayne

It works for rgb images. The only problem I still have is that the
createImage() method in the AWT toolkit does not decode 8 bit and 16 bit
images. The ImageJ part works like a charm!

Andy

Hinds vinod wrote:

>I have a jpeg image as an array of bytes. How can I display and save to it
>by a particular name in ImageJ without writing the  image out to a file?
>.May someone explain in details.
>Thanks.
>  
>
Reply | Threaded
Open this post in threaded view
|

Re: displaying JPEG image from array of byte

ctrueden
Hi Andy,

> It works for rgb images. The only problem I still have is that the
> createImage() method in the AWT toolkit does not decode 8 bit and 16
> bit images. The ImageJ part works like a charm!


When I saw Wayne's answer, I wrote a little test to see whether doing
things with ImageIO.read and BufferedImages offered any advantages. But
it appears the Toolkit way is about 25% faster than the ImageIO way.

On the other hand, it may be that ImageIO creates BufferedImages with
the proper ColorSpace/ColorModel/DataBuffer, instead of always RGB,
meaning you could extract the raw 8-bit or 16-bit values. I haven't
tested this, since I do not have any 8-bit or 16-bit JPEGs, but I'm
including my test code below so that you can try it out easily.

The code assumes RGB interleaved in a single byte bank, and thus
requires slight modification. There are a number of ways you can
determine if the BufferedImage represents 8-bit and 16-bit data. The
"proper" way would probably be to check the image's ColorModel. A
simpler way would be to compare bank.length vs w*h to get bytes per
pixel (3=RGB, 2=16-bit, 1=8-bit).

Good luck,
-Curtis

-----

//import java.awt.Image;
//import java.awt.Toolkit;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
import ij.ImagePlus;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;

public class JpegTest {
  public static void main(String[] args) throws Exception {
    // read bytes from JPEG file
    File file = new File("penguin.jpg");
    FileInputStream fin = new FileInputStream(file);
    byte[] bytes = new byte[(int) file.length()];
    int read = 0, left = bytes.length;
    while (left > 0) {
      int r = fin.read(bytes, read, left);
      read += r;
      left -= r;
    }
    fin.close();

    // construct image from raw bytes
    long start = System.currentTimeMillis();
    BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));

    // extract uncompressed bytes from image
    WritableRaster raster = img.getRaster();
    int w = img.getWidth(), h = img.getHeight();
    DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
    byte[] bank = buffer.getBankData()[0];
    int[] pix = new int[w * h];
    for (int i=0; i<pix.length; i++) {
      int ndx = 3 * i;
      int r = (bank[ndx] & 0xff);
      int g = (bank[ndx + 1] & 0xff) << 8;
      int b = (bank[ndx + 2] & 0xff) << 16;
      pix[i] = r | g | b;
    }
    ImageProcessor ip = new ColorProcessor(w, h, pix);
    new ImagePlus(file.getName(), ip).show();

//    Image img = Toolkit.getDefaultToolkit().createImage(bytes);
//    new ImagePlus(file.getName(), img).show();

    long end = System.currentTimeMillis();
    System.out.println("Time elapsed: " + (end - start) + " ms");
  }
}