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