Ignore:
Timestamp:
2017-09-04T18:52:06+02:00 (7 years ago)
Author:
bastiK
Message:

see #9995 - fix blurry GUI-icons and map view for Java 9 HiDPI mode

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/ImageResource.java

    r12682 r12722  
    3131     * Caches the image data for resized versions of the same image.
    3232     */
    33     private final Map<Dimension, Image> imgCache = new HashMap<>();
     33    private final Map<Dimension, BufferedImage> imgCache = new HashMap<>();
    3434    /**
    3535     * SVG diagram information in case of SVG vector image.
     
    151151
    152152    /**
    153      * Get an ImageIcon object for the image of this resource
     153     * Get an ImageIcon object for the image of this resource.
     154     * <p>
     155     * Will return a multi-resolution image by default (if possible).
    154156     * @param  dim The requested dimensions. Use (-1,-1) for the original size and (width, -1)
    155157     *         to set the width, but otherwise scale the image proportionally.
     158     * @see #getImageIconBounded(java.awt.Dimension, boolean)
    156159     * @return ImageIcon object for the image of this resource, scaled according to dim
    157160     */
    158161    public ImageIcon getImageIcon(Dimension dim) {
     162        return getImageIcon(dim, true);
     163    }
     164   
     165    /**
     166     * Get an ImageIcon object for the image of this resource.
     167     * @param  dim The requested dimensions. Use (-1,-1) for the original size and (width, -1)
     168     *         to set the width, but otherwise scale the image proportionally.
     169     * @param  multiResolution If true, return a multi-resolution image
     170     * (java.awt.image.MultiResolutionImage in Java 9), otherwise a plain {@link BufferedImage}.
     171     * When running Java 8, this flag has no effect and a plain image will be returned in any case.
     172     * @return ImageIcon object for the image of this resource, scaled according to dim
     173     * @since 12722
     174     */
     175    public ImageIcon getImageIcon(Dimension dim, boolean multiResolution) {
    159176        if (dim.width < -1 || dim.width == 0 || dim.height < -1 || dim.height == 0)
    160177            throw new IllegalArgumentException(dim+" is invalid");
    161         Image img = imgCache.get(dim);
    162         if (img != null) {
     178        BufferedImage img = imgCache.get(dim);
     179        if (img == null) {
     180            if (svg != null) {
     181                Dimension realDim = GuiSizesHelper.getDimensionDpiAdjusted(dim);
     182                img = ImageProvider.createImageFromSvg(svg, realDim);
     183                if (img == null) {
     184                    return null;
     185                }
     186            } else {
     187                if (baseImage == null) throw new AssertionError();
     188
     189                int realWidth = GuiSizesHelper.getSizeDpiAdjusted(dim.width);
     190                int realHeight = GuiSizesHelper.getSizeDpiAdjusted(dim.height);
     191                ImageIcon icon = new ImageIcon(baseImage);
     192                if (realWidth == -1 && realHeight == -1) {
     193                    realWidth = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconWidth());
     194                    realHeight = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconHeight());
     195                } else if (realWidth == -1) {
     196                    realWidth = Math.max(1, icon.getIconWidth() * realHeight / icon.getIconHeight());
     197                } else if (realHeight == -1) {
     198                    realHeight = Math.max(1, icon.getIconHeight() * realWidth / icon.getIconWidth());
     199                }
     200                Image i = icon.getImage().getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH);
     201                img = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
     202                img.getGraphics().drawImage(i, 0, 0, null);
     203            }
     204            if (overlayInfo != null) {
     205                for (ImageOverlay o : overlayInfo) {
     206                    o.process(img);
     207                }
     208            }
     209            if (isDisabled) {
     210                //Use default Swing functionality to make icon look disabled by applying grayscaling filter.
     211                Icon disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(null, new ImageIcon(img));
     212                if (disabledIcon == null) {
     213                    return null;
     214                }
     215
     216                //Convert Icon to ImageIcon with BufferedImage inside
     217                img = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
     218                disabledIcon.paintIcon(new JPanel(), img.getGraphics(), 0, 0);
     219            }
     220            imgCache.put(dim, img);
     221        }
     222
     223        if (!multiResolution)
    163224            return new ImageIcon(img);
    164         }
    165         BufferedImage bimg;
    166         if (svg != null) {
    167             Dimension realDim = GuiSizesHelper.getDimensionDpiAdjusted(dim);
    168             bimg = ImageProvider.createImageFromSvg(svg, realDim);
    169             if (bimg == null) {
    170                 return null;
    171             }
    172         } else {
    173             if (baseImage == null) throw new AssertionError();
    174 
    175             int realWidth = GuiSizesHelper.getSizeDpiAdjusted(dim.width);
    176             int realHeight = GuiSizesHelper.getSizeDpiAdjusted(dim.height);
    177             ImageIcon icon = new ImageIcon(baseImage);
    178             if (realWidth == -1 && realHeight == -1) {
    179                 realWidth = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconWidth());
    180                 realHeight = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconHeight());
    181             } else if (realWidth == -1) {
    182                 realWidth = Math.max(1, icon.getIconWidth() * realHeight / icon.getIconHeight());
    183             } else if (realHeight == -1) {
    184                 realHeight = Math.max(1, icon.getIconHeight() * realWidth / icon.getIconWidth());
    185             }
    186             Image i = icon.getImage().getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH);
    187             bimg = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
    188             bimg.getGraphics().drawImage(i, 0, 0, null);
    189         }
    190         if (overlayInfo != null) {
    191             for (ImageOverlay o : overlayInfo) {
    192                 o.process(bimg);
    193             }
    194         }
    195         if (isDisabled) {
    196             //Use default Swing functionality to make icon look disabled by applying grayscaling filter.
    197             Icon disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(null, new ImageIcon(bimg));
    198             if (disabledIcon == null) {
    199                 return null;
    200             }
    201 
    202             //Convert Icon to ImageIcon with BufferedImage inside
    203             bimg = new BufferedImage(bimg.getWidth(), bimg.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
    204             disabledIcon.paintIcon(new JPanel(), bimg.getGraphics(), 0, 0);
    205         }
    206         imgCache.put(dim, bimg);
    207         return new ImageIcon(bimg);
     225        else {
     226            try {
     227                Image mrImg = HiDPISupport.getMultiResolutionImage(img, this);
     228                return new ImageIcon(mrImg);
     229            } catch (NoClassDefFoundError e) {
     230                return new ImageIcon(img);
     231            }
     232        }
    208233    }
    209234
     
    211236     * Get image icon with a certain maximum size. The image is scaled down
    212237     * to fit maximum dimensions. (Keeps aspect ratio)
     238     * <p>
     239     * Will return a multi-resolution image by default (if possible).
    213240     *
    214241     * @param maxSize The maximum size. One of the dimensions (width or height) can be -1,
    215242     * which means it is not bounded.
    216243     * @return ImageIcon object for the image of this resource, scaled down if needed, according to maxSize
     244     * @see #getImageIconBounded(java.awt.Dimension, boolean)
    217245     */
    218246    public ImageIcon getImageIconBounded(Dimension maxSize) {
     247        return getImageIconBounded(maxSize, true);
     248    }
     249
     250    /**
     251     * Get image icon with a certain maximum size. The image is scaled down
     252     * to fit maximum dimensions. (Keeps aspect ratio)
     253     *
     254     * @param maxSize The maximum size. One of the dimensions (width or height) can be -1,
     255     * which means it is not bounded.
     256     * @param  multiResolution If true, return a multi-resolution image
     257     * (java.awt.image.MultiResolutionImage in Java 9), otherwise a plain {@link BufferedImage}.
     258     * When running Java 8, this flag has no effect and a plain image will be returned in any case.
     259     * @return ImageIcon object for the image of this resource, scaled down if needed, according to maxSize
     260     * @since 12722
     261     */
     262    public ImageIcon getImageIconBounded(Dimension maxSize, boolean multiResolution) {
    219263        if (maxSize.width < -1 || maxSize.width == 0 || maxSize.height < -1 || maxSize.height == 0)
    220264            throw new IllegalArgumentException(maxSize+" is invalid");
     
    240284
    241285        if (maxWidth == -1 && maxHeight == -1)
    242             return getImageIcon(DEFAULT_DIMENSION);
     286            return getImageIcon(DEFAULT_DIMENSION, multiResolution);
    243287        else if (maxWidth == -1)
    244             return getImageIcon(new Dimension(-1, maxHeight));
     288            return getImageIcon(new Dimension(-1, maxHeight), multiResolution);
    245289        else if (maxHeight == -1)
    246             return getImageIcon(new Dimension(maxWidth, -1));
     290            return getImageIcon(new Dimension(maxWidth, -1), multiResolution);
    247291        else if (sourceWidth / maxWidth > sourceHeight / maxHeight)
    248             return getImageIcon(new Dimension(maxWidth, -1));
     292            return getImageIcon(new Dimension(maxWidth, -1), multiResolution);
    249293        else
    250             return getImageIcon(new Dimension(-1, maxHeight));
     294            return getImageIcon(new Dimension(-1, maxHeight), multiResolution);
    251295   }
    252296}
Note: See TracChangeset for help on using the changeset viewer.