Skip to main content

"Universal" image reading

1 reply [Last post]
Anonymous

So I've written a limited Java EPS creator for image files using
BufferedImage and Image I/O, but it's not perfect.

I need to determine if it's RGB, CMYK, or grayscale (including 1-bit
B&W), get the bits per component, collect the samples in per-pixel
sequence in a certain order (RGB not BGR), and write my EPS. Oh, and
if there's an alpha channel, I need to get those values and handle
them specially.

Ascertaining type:

BufferedImage#getColorModel#getColorSpace#getType works for CMYK, but
for 1-bit B&W, it reports 8-bit RGB. BufferedImage#getType works for
1-bit B&W (BufferedImage.TYPE_BYTE_BINARY), but not for CMYK
(BufferedImage.TYPE_CUSTOM).

So already, I'm forced to use a different strategy for different kinds
of images. Do I have the right idea?

Accessing sample information with a ColorModel is easy.

final Object reusableDataArray = raster.getDataElements(x, y, null)
final int[] reusableSampleArray =
colorModel.getComponents(sampleArray, null, 0);
final int bitsPerComponent = colorModel.getComponentSize(0);

Accessing sample information from a Raster/SampleModel
(TYPE_BYTE_BINARY) isn't quite so easy.

BufferedImage#getType provides enough information to interpret the
output of Raster#getPixel, but that means I have to write new logic
for each #getType.

So right now, through trial and error I'm typing up a list of
BufferedImage.TYPE_*s that work well with ColorModel, and handling
them consistently. For each types that don't work well with
ColorModel, I'm writing special logic to interpret Raster#getPixel.

Am I on the right track, or am I just making this hard for myself?

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jim Graham

Hi Adam,

I haven't read through everything you've written here, but it sounds
like you've already learned about the major players here - there are
access methods at a number of levels - BufferedImage, Raster,
DataBuffer, and some helper methods on SampleModel and ColorModel as
well. The further down you dig, the faster things run since you are
closer to "the metal".

[Keep in mind that digging the DataBuffer out of a Raster will defeat
the "managed image" acceleration of BufferedImages in 1.6 and earlier -
1.7 will have a more flexible accounting scheme that lets you get the
DataBuffer from a BufferedImage as long as you don't call the getData()
method on the DataBuffer to get the raw Java array.]

Note that the simplest, easiest to use, jack of all trades, accessor
would be BufferedImage.getRGB(x, y) which returns a 32-bit ARGB value
regardless of the underlying image type. It won't be as fast as
analyzing the image and using the underlying methods that you've already
investigated, but it lets you get the job done if you fall through the
cracks of your image type detection code and it performs well enough for
smaller tasks - grabbing the value of the occasional pixel...

...jim

Adam Augusta wrote:
> So I've written a limited Java EPS creator for image files using
> BufferedImage and Image I/O, but it's not perfect.
>
> I need to determine if it's RGB, CMYK, or grayscale (including 1-bit
> B&W), get the bits per component, collect the samples in per-pixel
> sequence in a certain order (RGB not BGR), and write my EPS. Oh, and
> if there's an alpha channel, I need to get those values and handle
> them specially.
>
> Ascertaining type:
>
> BufferedImage#getColorModel#getColorSpace#getType works for CMYK, but
> for 1-bit B&W, it reports 8-bit RGB. BufferedImage#getType works for
> 1-bit B&W (BufferedImage.TYPE_BYTE_BINARY), but not for CMYK
> (BufferedImage.TYPE_CUSTOM).
>
> So already, I'm forced to use a different strategy for different kinds
> of images. Do I have the right idea?
>
> Accessing sample information with a ColorModel is easy.
>
> final Object reusableDataArray = raster.getDataElements(x, y, null)
> final int[] reusableSampleArray =
> colorModel.getComponents(sampleArray, null, 0);
> final int bitsPerComponent = colorModel.getComponentSize(0);
>
> Accessing sample information from a Raster/SampleModel
> (TYPE_BYTE_BINARY) isn't quite so easy.
>
> BufferedImage#getType provides enough information to interpret the
> output of Raster#getPixel, but that means I have to write new logic
> for each #getType.
>
> So right now, through trial and error I'm typing up a list of
> BufferedImage.TYPE_*s that work well with ColorModel, and handling
> them consistently. For each types that don't work well with
> ColorModel, I'm writing special logic to interpret Raster#getPixel.
>
> Am I on the right track, or am I just making this hard for myself?
>
> ===========================================================================
> To unsubscribe, send email to listserv@java.sun.com and include in the body
> of the message "signoff JAVA2D-INTEREST". For general help, send email to
> listserv@java.sun.com and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".