creating an ImagePlus from an InputStream or a byte[]

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

creating an ImagePlus from an InputStream or a byte[]

Johannes Hermen
Hi ImageJ Mailling List Users.

Does anybody knows a solution on how to create an ImagePlus directly from
a byte[] or an Inputstream.
The thing is that we want to show Images stored in a database blob without
creating a tempfile before.

It would be really nice to have something like this new ImagePlus(byte[])
or new ImagePlus(InputStream)

Thanks in advance
        Johannes

-----------------------------------------------------------------
Johannes Hermen  -  Ingenieur de Recherche
[hidden email]
-----------------------------------------------------------------
CRP Henri Tudor  http://www.santec.tudor.lu
29, Avenue John F. Kennedy
L-1855 Luxembourg
-----------------------------------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: creating an ImagePlus from an InputStream or a byte[]

Walking82
Hello Johannes

Try this:

InputStream myStream = ...;
ObjectInputStream ois = new ObjectInputStream(myStream);
ImagePlus ip = (ImagePlus) ois.readObject();

I hope this helps

Oliver

> Hi ImageJ Mailling List Users.
>
> Does anybody knows a solution on how to create an ImagePlus  
> directly from
> a byte[] or an Inputstream.
> The thing is that we want to show Images stored in a database blob  
> without
> creating a tempfile before.
>
> It would be really nice to have something like this new ImagePlus
> (byte[])
> or new ImagePlus(InputStream)
>
> Thanks in advance
>         Johannes
>
> -----------------------------------------------------------------
> Johannes Hermen  -  Ingenieur de Recherche
> [hidden email]
> -----------------------------------------------------------------
> CRP Henri Tudor  http://www.santec.tudor.lu
> 29, Avenue John F. Kennedy
> L-1855 Luxembourg
> -----------------------------------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: creating an ImagePlus from an InputStream or a byte[]

Johannes Hermen
ImageJ Interest Group <[hidden email]> wrote on 12.12.2007 12:44:55:

> > Does anybody knows a solution on how to create an ImagePlus
> > directly from
> > a byte[] or an Inputstream.
> > The thing is that we want to show Images stored in a database blob
> > without
> > creating a tempfile before.
> >
> > It would be really nice to have something like this new ImagePlus
> > (byte[])
> > or new ImagePlus(InputStream)
> Hello Johannes
>
> Try this:
>
> InputStream myStream = ...;
> ObjectInputStream ois = new ObjectInputStream(myStream);
> ImagePlus ip = (ImagePlus) ois.readObject();

That would only work if the byte[] is a serialized ImagePlus, but our
byte[] is an gif/png/jpg/bmp etc...

-----------------------------------------------------------------
Johannes Hermen  -  Ingenieur de Recherche
[hidden email]
-----------------------------------------------------------------
CRP Henri Tudor  http://www.santec.tudor.lu
29, Avenue John F. Kennedy
L-1855 Luxembourg
-----------------------------------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: creating an ImagePlus from an InputStream or a byte[]

Adrian Daerr-2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> That would only work if the byte[] is a serialized ImagePlus, but our
> byte[] is an gif/png/jpg/bmp etc...

Then let java.imageio.ImageIO.read(InputStream ...) convert it into a
BufferedImage, from which you can get the pixel data (with something
like getData().getPixels() for example). All of this untested of course...


- --
http://www.msc.univ-paris-diderot.fr/~daerr/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHYB6UUKl/wQSyHWgRArNuAJwI44fnMhpRFqva9Ey6x0bngnVsJwCfXnhf
A6pPEu5+3zdsELYufeRpIQQ=
=FH+b
-----END PGP SIGNATURE-----
Reply | Threaded
Open this post in threaded view
|

Re: creating an ImagePlus from an InputStream or a byte[]

ctrueden
In reply to this post by Johannes Hermen
Hi Johannes,

If your byte[] is a raw pixels block of 8-bit grayscale data, you can
use the ByteProcessor constructor:

public ByteProcessor(int width, int height, byte[] pixels,
java.awt.image.ColorModel cm)

However, if as you say your byte[] is a direct buffer from a GIF, PNG,
JPEG, BMP, or some other format, it is a bit more complicated. Three
possible ways are: 1) javax.imageio.ImageIO; 2) the ImageJ API; or 3)
Bio-Formats.

1) Using ImageIO is probably your easiest bet, assuming the formats
you need to support are limited to the common
(non-discipline-specific) single-plane image formats: JPEG, PNG, GIF,
BMP and TIFF.

BufferedImage img = ImageIO.read(new ByteArrayInputStream(myBytes));
ImagePlus imp = new ImagePlus(title, img);

But I don't think this approach will work for TIFF stacks, and more
exotic life sciences formats are right out.

2) ImageJ has separate logic for each format, which you could invoke
directly on a format-by-format basis.

For example, for TIFF, you could try the following:

TiffDecoder td = new TiffDecoder(new ByteArrayInputStream(myBytes), name);
FileInfo[] info = td.getTiffInfo();
ImagePlus imp = null;
if (info.length>1) { // try to open as stack
  imp = openTiffStack(info);
  if (imp!=null) return imp;
}
FileOpener fo = new FileOpener(info[0]);
imp = fo.open(false);
return imp;

I stole that code from ij.io.Opener, but adapted the TiffDecoder to
use the InputStream constructor instead. I haven't tested it, so do
not know for certain whether it will work.

With this approach, you would need to similarly adapt each individual
format you want to support.

There may also be a simpler "pure ImageJ" way of which I am ignorant.

3) Another option would be to use Bio-Formats, since it handles a
large number of multi-plane file formats and has a unified API to
avoid the need for format-specific logic.

In the process of whipping up some sample code, though, I realized the
latest Bio-Formats release does not actually have an API for feeding
in a byte array or InputStream directly to a reader, though 99% of the
logic to do it was there internally. So we have cooked up a
pre-release capable of doing so and placed it at:

http://skyking.microscopy.wisc.edu/curtis/jar/loci_tools.jar

And here is a code fragment:

import loci.formats.*;
import loci.plugins.Util;
...
IRandomAccess ira = new RABytes(myBytes);
// map the file to an id
String id = "myBytes"; // use whatever name you like here
Location.mapFile(id, ira);
// read the image planes
ImageReader r = new ImageReader();
r.setId(id);
int w = r.getSizeX();
int h = r.getSizeY();
int num = r.getImageCount();
ImageStack stack = new ImageStack(w, h);
for (int i=0; i<num; i++) {
  ImageProcessor ip = Util.openProcessor(r, i);
  stack.addSlice(id + ":" + i, ip);
}
ImagePlus imp = new ImagePlus(id, stack);

HTH,
Curtis

On Dec 12, 2007 8:35 AM, Johannes Hermen <[hidden email]> wrote:

> ImageJ Interest Group <[hidden email]> wrote on 12.12.2007 12:44:55:
>
> > > Does anybody knows a solution on how to create an ImagePlus
> > > directly from
> > > a byte[] or an Inputstream.
> > > The thing is that we want to show Images stored in a database blob
> > > without
> > > creating a tempfile before.
> > >
> > > It would be really nice to have something like this new ImagePlus
> > > (byte[])
> > > or new ImagePlus(InputStream)
> > Hello Johannes
> >
> > Try this:
> >
> > InputStream myStream = ...;
> > ObjectInputStream ois = new ObjectInputStream(myStream);
> > ImagePlus ip = (ImagePlus) ois.readObject();
>
> That would only work if the byte[] is a serialized ImagePlus, but our
> byte[] is an gif/png/jpg/bmp etc...
>
>
> -----------------------------------------------------------------
> Johannes Hermen  -  Ingenieur de Recherche
> [hidden email]
> -----------------------------------------------------------------
> CRP Henri Tudor  http://www.santec.tudor.lu
> 29, Avenue John F. Kennedy
> L-1855 Luxembourg
> -----------------------------------------------------------------
>
Reply | Threaded
Open this post in threaded view
|

Re: creating an ImagePlus from an InputStream or a byte[] -> SOLVED

Johannes Hermen
ImageJ Interest Group <[hidden email]> wrote on 12.12.2007 20:05:53:

> 1) Using ImageIO is probably your easiest bet, assuming the formats
> you need to support are limited to the common
> (non-discipline-specific) single-plane image formats: JPEG, PNG, GIF,
> BMP and TIFF.
>
> BufferedImage img = ImageIO.read(new ByteArrayInputStream(myBytes));
> ImagePlus imp = new ImagePlus(title, img);

This works for me so far.
Thanks a lot, I don't know why i didn't get this simple solution on my
own.....

I will keep in mind the other solutions for future problems ;-)

Anyway it would be nice to have a ImagePlus (or Opener) Constructor with
an InputStream, which shouldn't be that big problem. I think most of the
decoders and plugins used by the Opener Class work on an InputStream
anyway.

P.S. I allready Use the DICOM class and sun's TIFFDecoder to read Dicom
and Tiff images from a byte[], but it would be nice to have a general
solution.

-----------------------------------------------------------------
Johannes Hermen  -  Ingenieur de Recherche
[hidden email]
-----------------------------------------------------------------
CRP Henri Tudor  http://www.santec.tudor.lu
29, Avenue John F. Kennedy
L-1855 Luxembourg
-----------------------------------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: creating an ImagePlus from an InputStream or a byte[]

Dimiter Prodanov-2
In reply to this post by Johannes Hermen
 Hi Johannes,

I think, that it is best if you develop a protocol that specifies the format
of the blob; then to ues ByteArrayInputStream.
What comes in mind immediately is how would you cope with possible data
loss during transmission. I think that the only formats capable of coping
with that are GIF and JPEG as they are designed for images transmitted
over the internet.

Hope that it helps,

Dimiter