2

Following the idea of @PhiLho's answer to How to convert a BufferedImage to 8 bit?, I want to use ColorQuantizerDescriptor to convert a BufferedImage, imageType TYPE_INT_RGB, but RenderedOp#getColorModel() is throwing the following exception:

java.lang.IllegalArgumentException: The specified ColorModel is incompatible with the image SampleModel.
    at javax.media.jai.PlanarImage.setImageLayout(PlanarImage.java:541)
    at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:878)
    at javax.media.jai.RenderedOp.getColorModel(RenderedOp.java:2253)

This is the code that I am attempting to use:

final RenderedOp medianCutQuantizerOp = ColorQuantizerDescriptor.create(rgbImage, ColorQuantizerDescriptor.MEDIANCUT, 256, null, null, null, null, null);
final BufferedImage bi = medianCutQuantizerOp.getAsBufferedImage(null, medianCutQuantizerOp.getColorModel());

How do I use ColorQuantizerDescriptor?

Community
  • 1
  • 1
Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193
  • I find it hard to believe that a getter is throwing the exception. Try breaking out the call to getColorModel on its own line then pass that var into the getAsBufferedImage call. I think you'll see the error comes from the getAsBufferedImage call. From http://download.java.net/media/jai/javadoc/1.1.3/jai-apidocs/javax/media/jai/PlanarImage.html#getAsBufferedImage(java.awt.Rectangle, java.awt.image.ColorModel) - "The caller is responsible for supplying a ColorModel that is compatible with the image's SampleModel. " – I82Much Mar 09 '13 at 17:07
  • @I82Much getColorModel() can throw an exception (though it is not documented!) because it can create a rendering of the Op in order to get the model. – PhiLho Jun 24 '13 at 09:34

1 Answers1

3

The following example has been modified from http://code.google.com/p/color-reduction-experiments/source/browse/trunk/it/geosolutions/mapproducers/MapProducersTest.java?r=2

public class Main {
    public static void main(String[] args) throws Exception {

        BufferedImage original = ImageIO.read(new File("/Users/Nick/Desktop/with_flowers.jpg"));
         // 300 seems to be a good number
        final RenderedOp cqImage = ColorQuantizerDescriptor.create(
           original, ColorQuantizerDescriptor.OCTTREE,
           new Integer(255), new Integer(300), null, new Integer(2),
           new Integer(2), null);

        assert cqImage.getColorModel() instanceof IndexColorModel;
        final BufferedImage converted = cqImage.getAsBufferedImage();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JFrame f = new JFrame();
                f.setTitle("Test");
                f.getContentPane().add((new ScrollingImagePanel(converted, 300, 300)));
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

Works for me:Using octree

Edit: tried with your median cut and seems to work as well, though much slower.

Using median cut

I82Much
  • 26,901
  • 13
  • 88
  • 119
  • 1
    Interesting. The image type of `original` when I run this is 5 (TYPE_3BYTE_BGR). If I modify the code to create a new `BufferedImage`, TYPE_INT_RGB, and drawImage() the original into the TYPE_INT_RGB image, then `cqImage.getAsBufferedImage()` throws "IllegalArgumentException: The specified ColorModel is incompatible with the image SampleModel". Apparently some image types work but others do not? – Daniel Trebbien Mar 09 '13 at 18:01
  • It might be helpful if you upload the image you can't get to work. – I82Much Mar 09 '13 at 18:35
  • The image is generated and I don't think that I can release it. It's okay, though. I think this answers my question in that yes, this is how `ColorQuantizerDescriptor` is used, but there are some restrictions. – Daniel Trebbien Mar 09 '13 at 19:34
  • 1
    I had a similar problem with screenshots (probably generated with AWT's Robot), and solved it by drawing the image on a TYPE_3BYTE_BGR BufferedImage before quantizing it. – PhiLho Jun 25 '13 at 05:28