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

corrupted toplevel icon on scaled image

XMLWordPrintable

    • b85
    • 6
    • b95
    • generic
    • windows_2000

      Setting a scaled image as an icon for frame leads to wrong painting of icon that appears on ALT+TAB and of icon in the task bar. First one contains two vertical lines, second one vertical line in the center.
      See you should use image with size different from 32x32 pixels.
      Run test with image say 30x30 and press ALT+TAB. Also note vert. line in the icon from the task bar.
      This seen only on Windows platform.
      Pretty well noticeable on Windows2000. Less visible on WindowsXP.

      import java.awt.*;
      import java.awt.event.*;
      import java.awt.image.*;
      import java.util.Iterator;

      public class TestScale extends Frame{
      // public static Frame frame;
          private Button buttonSimple;
          public static Image image; // = frame.getIconImage();
          public static java.util.List<Image> images;
          static String fileBase;
          static String fileName;

          public static void main (String s[]){
              if (System.getProperty("test.src") == null){
                  fileBase = "";
              } else {
                  fileBase = System.getProperty("test.src") + System.getProperty("file.separator");
              }

              fileName = "images"+System.getProperty("file.separator") + "cross.jpg";

              Frame frame = new TestScale();

              frame.setSize(500, 500);
              frame.setVisible(true);
          }

          public void paint(Graphics g){
             g.setColor(Color.black);
             g.fillRect(0, 0, this.getWidth(), this.getHeight());
             Image image;
             Image scaledImage;
             try {
                 image = Toolkit.getDefaultToolkit().getImage(fileName);
      // if ( != null){
                     System.out.println("setting to frame");
                     this.setIconImage(image);
      // }
                 g.drawImage(image, 100, 100, null);
                 System.out.println("Loaded image.");
                 java.util.List imageList = new java.util.ArrayList();
                 imageList.add(image);
                 scaledImage = getScaledIconImage(imageList, 100, 100);
                 g.drawImage(scaledImage, 300, 300, null);


                 scaledImage = getScaledIconImage(imageList, 16, 16);
                 g.drawImage(scaledImage, 400, 400, null);

                 scaledImage = getScaledIconImage(imageList, 32, 32);
                 g.drawImage(scaledImage, 450, 400, null);

                 scaledImage = getScaledIconImage(imageList, 48, 48);
                 g.drawImage(scaledImage, 450, 450, null);

             } catch (Exception e) {
                 e.printStackTrace();
             }
          }

          public static BufferedImage getScaledIconImage(java.util.List<Image> imageList, int width, int height) {
              if (width == 0 || height == 0) {
                  return null;
              }
              Image bestImage = null;
              int bestWidth = 0;
              int bestHeight = 0;
              double bestSimilarity = 3; //Impossibly high value
              double bestScaleFactor = 0;
              for (Iterator<Image> i = imageList.iterator();i.hasNext();) {
                  Image im = i.next();
                  if (im == null) {
                      continue;
                  }
                  int iw;
                  int ih;

                  try {
                      iw = im.getWidth(null);
                      ih = im.getHeight(null);
                  } catch (Exception e){
                      continue;
                  }
                  
                  if (iw > 0 && ih > 0) {
                      //Calc scale factor
                      double scaleFactor = Math.min((double)width / (double)iw,
                                                    (double)height / (double)ih);
                      //Calculate scaled image dimensions
                      //adjusting scale factor to nearest "good" value
                      int adjw = 0;
                      int adjh = 0;
                      double scaleMeasure = 1; //0 - best (no) scale, 1 - impossibly bad
                      if (scaleFactor >= 2) {
                          //Need to enlarge image more than twice
                          //Round down scale factor to multiply by integer value
                          scaleFactor = Math.floor(scaleFactor);
                          adjw = iw * (int)scaleFactor;
                          adjh = ih * (int)scaleFactor;
                          scaleMeasure = 1.0 - 0.5 / scaleFactor;
                      } else if (scaleFactor >= 1) {
                          //Don't scale
                          scaleFactor = 1.0;
                          adjw = iw;
                          adjh = ih;
                          scaleMeasure = 0;
                      } else if (scaleFactor >= 0.75) {
                          //Multiply by 3/4
                          scaleFactor = 0.75;
                          adjw = iw * 3 / 4;
                          adjh = ih * 3 / 4;
                          scaleMeasure = 0.3;
                      } else if (scaleFactor >= 0.6666) {
                          //Multiply by 2/3
                          scaleFactor = 0.6666;
                          adjw = iw * 2 / 3;
                          adjh = ih * 2 / 3;
                          scaleMeasure = 0.33;
                      } else {
                          //Multiply size by 1/scaleDivider
                          //where scaleDivider is minimum possible integer
                          //larger than 1/scaleFactor
                          double scaleDivider = Math.ceil(1.0 / scaleFactor);
                          scaleFactor = 1.0 / scaleDivider;
                          adjw = (int)Math.round((double)iw / scaleDivider);
                          adjh = (int)Math.round((double)ih / scaleDivider);
                          scaleMeasure = 1.0 - 1.0 / scaleDivider;
                      }
                      double similarity = ((double)width - (double)adjw) / (double)width +
                          ((double)height - (double)adjh) / (double)height + //Large padding is bad
                          scaleMeasure; //Large rescale is bad
                      if (similarity < bestSimilarity) {
                          bestSimilarity = similarity;
                          bestScaleFactor = scaleFactor;
                          bestImage = im;
                          bestWidth = adjw;
                          bestHeight = adjh;
                      }
                      if (similarity == 0) break;
                  }
              }
              if (bestImage == null) {
                  //No images were found, possibly all are broken
                  return null;
              }
              BufferedImage bimage =
                  new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
              Graphics2D g = bimage.createGraphics();
              g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
              try {
                  int x = (width - bestWidth) / 2;
                  int y = (height - bestHeight) / 2;
                  g.drawImage(bestImage, x, y, bestWidth, bestHeight, null);
              } finally {
                  g.dispose();
              }
              return bimage;
          }

      }

            vbaranovsunw Vyacheslav Baranov (Inactive)
            dav Andrei Dmitriev (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: