Skip to main content

[JAI] Bug with drawing color-reduced image on TiledImage(?)

1 reply [Last post]
Anonymous

Hi,

I am getting an exception when drawing a color-reduced image on a Graphics
object created from a TiledImage. Apparently it is caused by an incompatible
BytePackedRaster and IndexColorModel. I am including sample code below; it
should run as a standalone app.

The problem is that by changing a couple of small details, I can get the
code to run without problems. These changes include:

- using a 15 color palette instead of 16 for the error diffusion
- setting the bilinear interpolation rendering hint on the graphics instead
of nearest neighbor
- using the identity transform on the drawImage method instead of a scale
and translate

I am very unclear as to why I am getting the error in the first place, since
I am creating my TiledImage based on the color-reduced image's color model
and sample model. The fact that the error disappears with apparently
unrelated changes hints that maybe this is a bug... Does anyone have an idea
as to what the problem is or if there is a workaround?

Thanks!
Marc

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.renderable.ParameterBlock;

import javax.media.jai.BorderExtender;
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
import javax.media.jai.KernelJAI;
import javax.media.jai.LookupTableJAI;
import javax.media.jai.TiledImage;
import javax.media.jai.operator.FileLoadDescriptor;
import javax.swing.JFrame;

import com.sun.media.jai.widget.DisplayJAI;

public class SampleCode {

public static void main(String[] args) {
JFrame frame = new JFrame("SAMPLE CODE");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
DisplayJAI display = new DisplayJAI();

String imagefile = "images/charlott128x128.jpg";

RenderedImage output = genImage(imagefile);

display.set(output);
frame.getContentPane().add(display);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}

static RenderedImage genImage(String file) {

RenderedImage reImg = FileLoadDescriptor.create(file, null, null, null);

// *** Color reduction ****
// REMOVE THE LAST ENTRY OF EACH SUBARRAY AND THIS CODE WILL RUN
// ie. make this a [3][15] array instead of [3][16]
byte[][] palette = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte)0x88,
(byte)0x99, (byte)0xAA, (byte)0xBB, (byte)0xCC, (byte)0xDD,
(byte)0xEE, (byte)0xFF },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
byte[][] outputLUT = palette;
ColorModel cm = new IndexColorModel(4, outputLUT[0].length,
outputLUT[0], outputLUT[1], outputLUT[2]);
ImageLayout il = new ImageLayout();
il.setColorModel(cm);
RenderingHints rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, il);

ParameterBlock pb = new ParameterBlock();
pb.addSource(reImg);
pb.add(new LookupTableJAI(outputLUT));
pb.add(KernelJAI.ERROR_FILTER_FLOYD_STEINBERG);
BorderExtender be = BorderExtender
.createInstance(BorderExtender.BORDER_COPY);
rh.add(new RenderingHints(JAI.KEY_BORDER_EXTENDER, be));
reImg = JAI.create("ErrorDiffusion", pb, rh);

// *** Draw image on graphics ****
int gwidth = 128;
int gheight = 64;

SampleModel sm =
reImg.getSampleModel().createCompatibleSampleModel(gwidth,
gheight);
TiledImage ti = new TiledImage(0, 0, gwidth, gheight, 0, 0, sm, cm);
Graphics2D g2d = ti.createGraphics();

// SET TO RenderingHints.VALUE_INTERPOLATION_BILINEAR TO MAKE CODE RUN
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

// USE IDENTITY TRANSFORM INSTEAD TO MAKE THIS CODE WORK
// ie AffineTransform at = new AffineTransform();
AffineTransform at = new AffineTransform(0.5, 0, 0, 0.5, 32, 0);
g2d.drawRenderedImage(reImg, at);

return ti;
}
}

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Reply viewing options

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

Marc,

This looks like a Java2D bug which has been fixed in Java 5. I was able to
reproduce the problem when using 1.4.2_04 but not with 1.5.0_01. I do not know
the associated bug ID.

Brian

On Tue, 21 Jun 2005, Marc Boscher wrote:

> Hi,
>
> I am getting an exception when drawing a color-reduced image on a Graphics
> object created from a TiledImage. Apparently it is caused by an incompatible
> BytePackedRaster and IndexColorModel. I am including sample code below; it
> should run as a standalone app.
>
> The problem is that by changing a couple of small details, I can get the
> code to run without problems. These changes include:
>
> - using a 15 color palette instead of 16 for the error diffusion
> - setting the bilinear interpolation rendering hint on the graphics instead
> of nearest neighbor
> - using the identity transform on the drawImage method instead of a scale
> and translate
>
> I am very unclear as to why I am getting the error in the first place, since
> I am creating my TiledImage based on the color-reduced image's color model
> and sample model. The fact that the error disappears with apparently
> unrelated changes hints that maybe this is a bug... Does anyone have an idea
> as to what the problem is or if there is a workaround?
>
> Thanks!
> Marc
>
> import java.awt.Graphics2D;
> import java.awt.RenderingHints;
> import java.awt.geom.AffineTransform;
> import java.awt.image.ColorModel;
> import java.awt.image.IndexColorModel;
> import java.awt.image.RenderedImage;
> import java.awt.image.SampleModel;
> import java.awt.image.renderable.ParameterBlock;
>
> import javax.media.jai.BorderExtender;
> import javax.media.jai.ImageLayout;
> import javax.media.jai.JAI;
> import javax.media.jai.KernelJAI;
> import javax.media.jai.LookupTableJAI;
> import javax.media.jai.TiledImage;
> import javax.media.jai.operator.FileLoadDescriptor;
> import javax.swing.JFrame;
>
> import com.sun.media.jai.widget.DisplayJAI;
>
> public class SampleCode {
>
> public static void main(String[] args) {
> JFrame frame = new JFrame("SAMPLE CODE");
> frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
> DisplayJAI display = new DisplayJAI();
>
> String imagefile = "images/charlott128x128.jpg";
>
> RenderedImage output = genImage(imagefile);
>
> display.set(output);
> frame.getContentPane().add(display);
> frame.setLocationRelativeTo(null);
> frame.pack();
> frame.setVisible(true);
> }
>
> static RenderedImage genImage(String file) {
>
> RenderedImage reImg = FileLoadDescriptor.create(file, null, null, null);
>
> // *** Color reduction ****
> // REMOVE THE LAST ENTRY OF EACH SUBARRAY AND THIS CODE WILL RUN
> // ie. make this a [3][15] array instead of [3][16]
> byte[][] palette = {
> { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
> { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte)0x88,
> (byte)0x99, (byte)0xAA, (byte)0xBB, (byte)0xCC, (byte)0xDD,
> (byte)0xEE, (byte)0xFF },
> { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
> byte[][] outputLUT = palette;
> ColorModel cm = new IndexColorModel(4, outputLUT[0].length,
> outputLUT[0], outputLUT[1], outputLUT[2]);
> ImageLayout il = new ImageLayout();
> il.setColorModel(cm);
> RenderingHints rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, il);
>
> ParameterBlock pb = new ParameterBlock();
> pb.addSource(reImg);
> pb.add(new LookupTableJAI(outputLUT));
> pb.add(KernelJAI.ERROR_FILTER_FLOYD_STEINBERG);
> BorderExtender be = BorderExtender
> .createInstance(BorderExtender.BORDER_COPY);
> rh.add(new RenderingHints(JAI.KEY_BORDER_EXTENDER, be));
> reImg = JAI.create("ErrorDiffusion", pb, rh);
>
> // *** Draw image on graphics ****
> int gwidth = 128;
> int gheight = 64;
>
> SampleModel sm =
> reImg.getSampleModel().createCompatibleSampleModel(gwidth,
> gheight);
> TiledImage ti = new TiledImage(0, 0, gwidth, gheight, 0, 0, sm, cm);
> Graphics2D g2d = ti.createGraphics();
>
> // SET TO RenderingHints.VALUE_INTERPOLATION_BILINEAR TO MAKE CODE RUN
> g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
> RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
>
> // USE IDENTITY TRANSFORM INSTEAD TO MAKE THIS CODE WORK
> // ie AffineTransform at = new AffineTransform();
> AffineTransform at = new AffineTransform(0.5, 0, 0, 0.5, 32, 0);
> g2d.drawRenderedImage(reImg, at);
>
> return ti;
> }
> }
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net
>
>

----------------
Brian Burkhalter
Advanced Development/Media & Entertainment
Market Development Engineering
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net