Re: displaying JPEG image from array of byte

Posted by ctrueden on
URL: http://imagej.273.s1.nabble.com/displaying-JPEG-image-from-array-of-byte-tp3703272p3703274.html

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");
  }
}