2

Using the code found here, I've written code that stores image data where each color component is a floating point value.

// Create a TYPE_FLOAT sample model (specifying how the pixels are stored)
SampleModel sampleModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_FLOAT, options.width, options.height, 4, options.width * 4, new int[]{0,1,2,3});
// ...and data buffer (where the pixels are stored)
DataBufferFloat buffer = new DataBufferFloat(options.width * options.height * 4);

// Wrap it in a writable raster
WritableRaster raster = Raster.createWritableRaster(sampleModel, buffer, null);

// Create a color model compatible with this sample model/raster (TYPE_FLOAT)
// Note that the number of bands must equal the number of color components in the 
// color space (3 for RGB) + 1 extra band if the color model contains alpha 
ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel colorModel = new ComponentColorModel(colorSpace, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_FLOAT);

// And finally create an image with this raster
BufferedImage out = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);
float[] backingImageData = buffer.getData();

FloatBuffer data = /*External Image Data Source...*/;
data.get(backingImageData); //Place data in image

boolean writerFound = ImageIO.write(out, "png", new File("C:\\out.png"));

However, this code is failing because ImageIO is failing to find an appropriate writer for this custom image configuration (as seen when debugging, where writerFound is false). How do I get ImageIO to successfully write data with this image?

Xirema
  • 19,889
  • 4
  • 32
  • 68
  • I think that you should convert your image to another type. Check out [this question](https://stackoverflow.com/questions/8194080/converting-a-bufferedimage-to-another-type). – vbezhenar Feb 28 '20 at 23:22
  • Post the stack trace. Always provide the exact error message, not your paraphrase of what you think it says. – user207421 Feb 29 '20 at 02:07
  • 1
    @user207421 There's no stack trace, because there's no exception thrown. `writerFound` is false when the `ImageIO.write` function fails. – Xirema Feb 29 '20 at 02:47
  • Well then don't guess. The [Javadoc](https://docs.oracle.com/javase/8/docs/api/javax/imageio/ImageIO.html#write-java.awt.image.RenderedImage-java.lang.String-java.io.File-) says 'writes an image using an arbitrary `ImageWriter` that supports the given format to a `File`.' and 'returns false if no appropriate writer is found.' Nothing there about 'failing to find an appropriate writer *for this custom image configuration*'. And I don't see what the three lines after `BufferedImage out = ...` have to do with anything. Are they in the right place? – user207421 Feb 29 '20 at 03:51
  • 2
    @user207421 The comments are very clear: `data` represents the raw bitmap (in floating point format) that then gets bulk-copied into `backingImageData`, which I then attempt to write. I'm not "guessing" anything, "returns false if no appropriate writer is found" and "failing to find an appropriate writer" are the same thing, why are you hounding the precise wording of my problem, when it's clear what I'm talking about? – Xirema Feb 29 '20 at 04:00
  • Not many formats allows storing data as floating point (ie. JPEG, PNG, GIF etc won't do here), regardless of ImageIO. It's just a limitation of the file formats. I think TIFF could work, and there's a PNM variant for floating point. Probably some HDR intermediate formats allows it. But still, I'm not sure if there are ImageIO plugins that supports any of these formats in floating point. Do you need all that information? Or do you just need to write a PNG for display purposes? – Harald K Mar 02 '20 at 12:35
  • @haraldK "The PNG Format doesn't support floating point; you'll need to use a different image format" is probably better posted as an answer. – Xirema Mar 02 '20 at 15:25
  • Depends on what you need. You could either use a different format (that supports floating point), or you could convert your floating point image to a normal integral type and use PNG format. Is it the floating point sample values you need or just the visual representation? – Harald K Mar 02 '20 at 16:41
  • @haraldK The floating point sample values are what I need. – Xirema Mar 02 '20 at 17:31

1 Answers1

2

To write an image containing floating point values to file, you need:

a) A format that allows storing floating point values. Most image formats, including JPEG, PNG or GIF certainly don't. The most commonly used file format I know that does, is TIFF. Still, it's worth noting that floating point TIFF is not "baseline" TIFF, so not all TIFF software will support these kind of files.

b) An ImageIO plug-in that supports writing TIFF in floating point. I think JAI may work, and pretty sure GeoTools does. My own plugin supports reading but not writing floating point at the moment (but creating a change set for this should be fairly easy, should you feel adventurous).

With that sorted, the following should work (given out is the same floating point image as in your code):

ImageIO.write(out, "TIFF", new File("C:\\out.tif"));
Harald K
  • 26,314
  • 7
  • 65
  • 111