If what you're trying to do is get the pixel data as an array, then you can use ImageIO.read()
to get a BufferedImage
and then use BufferedImage.getRaster().getDataBuffer()
to get the DataBuffer
. From there, you need to check what type of BufferedImage
you have in order to determine how to cast the DataBuffer
. E.g. if you have a TYPE_INT_RGB
image, then you should cast to a DataBufferInt
and then you can call DataBufferInt.getData()
to retrieve the int[]
which contains the data. What you get this way is not a copy---it's the actual array backing the BufferedImage
.
However, there is a big caveat to all of this: ImageIO.read()
will often NOT give you the type of image you want. E.g., you'll frequently get TYPE_CUSTOM, which you can't do anything useful with except copy to the image type you actually want.
So, you'll only be able to get your image data via ImageIO.read()
without making a second copy if you're fortunate enough that ImageIO.read()
gives you the image in the format you want. If you want to check what types are available from ImageIO
, you can call ImageIO.getImageReaders()
to get an Iterator
over all of the readers which claim to be able to read your stream, and then you can use ImageReader.getImageTypes(0)
to get an Iterator
over image types which the reader can read. You might find a reader which will give you the image type you want this way, but don't hold your breath.
Unless your images are huge, copying them is actually pretty fast. If your images are huge, though, you might have to resort to using BufferedImage.getRGB()
to write the raw image data out to disk one row at a time (but do it compressed, use a GZIPOutputStream
), let the original image be garbage collected, create a new BufferedImage
of the desired type, and finally read the rows back from disk, writing them to the new image using BufferedImage.setRGB()
. (I wrote something to do this just a few days ago, hence the details are rather fresh in my mind. The LGPL'd source for it is here.)