Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4243044

Java2D displays Gray/Alpha images incorrectly

XMLWordPrintable

    • 2d
    • 1.3
    • generic
    • solaris_7
    • Not verified

        The included test program pops up six display windows. All display a
      checkerboard image. Each window varies whether the image is represented
      as monochrome or RGB, with or without alpha, and (if with alpha) whether the
      alpha channel is premultiplied into the other channels.

        All the windows but two display correctly. The incorrect windows are
      those attempting to display Gray + Alpha, premultiplied or not. The symptoms
      are horizontal stretching and alternation of values from the gray and alpha
      channels, as well as incorrect partial updates (e.g. when a window is dragged
      across).

        With the introduction of support for PNG in Java2D and JAI, and JAI support
      for FlashPIX and IIP, Gray + Alpha imagery will become more commonly used and
      thus the probability of customers encountering this problem is increased.

      import java.awt.*;
      import java.awt.color.*;
      import java.awt.geom.*;
      import java.awt.image.*;

      public class GrayAlpha extends Canvas {

          BufferedImage bi;
          AffineTransform identityTransform = new AffineTransform();

          public GrayAlpha(int width, int height,
                           boolean hasAlpha, boolean isAlphaPremultiplied,
                           boolean useRGB) {
              boolean isAlphaPremuliplied = true;
              int bands = useRGB ? 3 : 1;
              bands = hasAlpha ? bands + 1 : bands;

              ColorSpace cs = useRGB ?
                  ColorSpace.getInstance(ColorSpace.CS_sRGB) :
                  ColorSpace.getInstance(ColorSpace.CS_GRAY);
              int transparency = hasAlpha ?
                  Transparency.TRANSLUCENT : Transparency.OPAQUE;
              int[] bits = new int[bands];
              for (int i = 0; i < bands; i++) {
                  bits[i] = 8;
              }

              ColorModel cm = new ComponentColorModel(cs,
                                                      bits,
                                                      hasAlpha,
                                                      isAlphaPremultiplied,
                                                      transparency,
                                                      DataBuffer.TYPE_BYTE);
              WritableRaster wr =
                  Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                                                 width, height, bands,
                                                 new Point(0, 0));
              
              for (int b = 0; b < bands; b++) {
                  for (int y = 0; y < height; y++) {
                      for (int x = 0; x < width; x++) {
                          int s;

                          if (b != bands - 1 || !hasAlpha) {
                              // Gray band(s), fill with a checkerboard pattern
                              if (((x / 10) % 2) == ((y / 10) % 2)) {
                                  s = 255;
                              } else {
                                  s = 0;
                              }
                              if (isAlphaPremultiplied) {
                                  int alpha = (x*255)/(width - 1);
                                  s = (s*alpha)/255;
                              }
                          } else {
                              // Alpha band, increase opacity left to right
                              s = (x*255)/(width - 1);
                          }

                          wr.setSample(x, y, b, s);
                      }
                  }
              }
                                                                 
              this.bi = new BufferedImage(cm, wr, isAlphaPremultiplied, null);
          }

          public Dimension getPreferredSize() {
              return new Dimension(bi.getWidth(), bi.getHeight());
          }

          public void paint(Graphics g) {
              ((Graphics2D)g).drawImage(bi, 0, 0, null);
          }

          public static void makeFrame(String title,
                                       int x, int y, int width, int height,
                                       boolean hasAlpha,
                                       boolean isAlphaPremultiplied,
                                       boolean useRGB) {
              Frame f = new Frame(title);
              f.add(new GrayAlpha(width, height,
                                  hasAlpha, isAlphaPremultiplied, useRGB));
              f.pack();
              f.setLocation(x, y);
              f.setVisible(true);
          }

          public static void main(String[] args) {
              int width = 200;
              int height = 200;

              int x = 100;
              int y = 100;

              makeFrame("Gray w/o Alpha",
                        x, y, width, height,
                        false, false, false);
              x += width + 20;
              makeFrame("Gray (non-premultiplied)",
                        x, y, width, height,
                        true, false, false);
              x += width + 20;
              makeFrame("Gray (premultiplied)",
                        x, y, width, height,
                        true, true, false);

              x = 100;
              y += height + 50;
              makeFrame("RGB w/o Alpha",
                        x, y, width, height,
                        false, false, true);
              x += width + 20;
              makeFrame("RGBA (non-premultiplied)",
                        x, y, width, height,
                        true, false, true);
              x += width + 20;
              makeFrame("RGBA (premultiplied)",
                        x, y, width, height,
                        true, true, true);
          }
      }

            busersunw Btplusnull User (Inactive)
            dricesunw Daniel Rice (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: