Index: /trunk/src/org/openstreetmap/josm/gui/SideButton.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/SideButton.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/gui/SideButton.java	(revision 10358)
@@ -92,5 +92,5 @@
             action.addPropertyChangeListener(propertyChangeListener);
         }
-        int iconHeight = ImageProvider.ImageSizes.SIDEBUTTON.getImageSize();
+        int iconHeight = ImageProvider.ImageSizes.SIDEBUTTON.getImageDimension().height;
         Icon i = getIcon();
         if (i instanceof ImageIcon && i.getIconHeight() != iconHeight) {
Index: /trunk/src/org/openstreetmap/josm/gui/SplashScreen.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/SplashScreen.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/gui/SplashScreen.java	(revision 10358)
@@ -9,5 +9,4 @@
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
-import java.awt.Image;
 import java.awt.Insets;
 import java.awt.event.MouseAdapter;
@@ -18,5 +17,4 @@
 
 import javax.swing.BorderFactory;
-import javax.swing.ImageIcon;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
@@ -70,5 +68,5 @@
 
         // Add the logo
-        JLabel logo = new JLabel(new ImageIcon(ImageProvider.get("logo.svg").getImage().getScaledInstance(128, 129, Image.SCALE_SMOOTH)));
+        JLabel logo = new JLabel(new ImageProvider("logo.svg").setSize(ImageProvider.ImageSizes.SPLASH_LOGO).get());
         GridBagConstraints gbc = new GridBagConstraints();
         gbc.gridheight = 2;
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 10358)
@@ -34,4 +34,5 @@
 import javax.swing.BorderFactory;
 import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
 import javax.swing.JButton;
 import javax.swing.JCheckBoxMenuItem;
@@ -506,5 +507,6 @@
 
             // scale down the dialog icon
-            lblTitle = new JLabel("", new ImageProvider("dialogs", iconName).setWidth(16).get(), JLabel.TRAILING);
+            ImageIcon icon = new ImageProvider("dialogs", iconName).setSize(ImageProvider.ImageSizes.SMALLICON).get();
+            lblTitle = new JLabel("", icon, JLabel.TRAILING);
             lblTitle.setIconTextGap(8);
 
@@ -543,5 +545,5 @@
             // show the pref button if applicable
             if (preferenceClass != null) {
-                JButton pref = new JButton(new ImageProvider("preference").setWidth(16).get());
+                JButton pref = new JButton(new ImageProvider("preference").setSize(ImageProvider.ImageSizes.SMALLICON).get());
                 pref.setToolTipText(tr("Open preferences for this panel"));
                 pref.setBorder(BorderFactory.createEmptyBorder());
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 10358)
@@ -147,5 +147,5 @@
     public static ImageIcon getIcon(IconReference ref, int width, int height) {
         final String namespace = ref.source.getPrefName();
-        ImageIcon i = getIconProvider(ref, false).setWidth(width).setHeight(height).get();
+        ImageIcon i = getIconProvider(ref, false).setSize(width, height).get();
         if (i == null) {
             Main.warn("Mappaint style \""+namespace+"\" ("+ref.source.getDisplayString()+") icon \"" + ref.iconName + "\" not found.");
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 10358)
@@ -510,8 +510,8 @@
                     // Get icon
                     String iconName = tps.getIconName();
-                    ImageIcon icon = iconName != null && !iconName.isEmpty() ? ImageProvider.get("preferences", iconName) : null;
-                    // See #6985 - Force icons to be 48x48 pixels
-                    if (icon != null && (icon.getIconHeight() != 48 || icon.getIconWidth() != 48)) {
-                        icon = new ImageIcon(icon.getImage().getScaledInstance(48, 48, Image.SCALE_DEFAULT));
+                    ImageIcon icon = null;
+
+                    if(iconName != null && !iconName.isEmpty()) {
+                        icon = new ImageProvider("preferences", iconName).setSize(ImageProvider.ImageSizes.SETTINGS_TAB).get();
                     }
                     if (settingsInitialized.contains(tps)) {
Index: /trunk/src/org/openstreetmap/josm/gui/util/GuiSizesHelper.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/util/GuiSizesHelper.java	(revision 10358)
+++ /trunk/src/org/openstreetmap/josm/gui/util/GuiSizesHelper.java	(revision 10358)
@@ -0,0 +1,99 @@
+package org.openstreetmap.josm.gui.util;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+
+/**
+ * Support class to handle size information of Gui elements
+ * This is needed, because display resolution may vary a lot and a common set
+ * of sizes wont work for all users alike.
+ * @since 10358
+ */
+public class GuiSizesHelper {
+    /** cache value for screen resolution */
+    private static int screenDPI = -1;
+
+    /** Request the screen resolution (cached)
+     * @return screen resolution in DPI
+     */
+    private static int getScreenDPI() {
+        if (screenDPI == -1) {
+            synchronized (GuiHelper.class) {
+                if (screenDPI == -1) {
+                    screenDPI = Toolkit.getDefaultToolkit().getScreenResolution();
+                }
+            }
+        }
+        return screenDPI;
+    }
+
+    /**
+     * Returns coefficient of monitor pixel density. All hardcoded sizes must be multiplied by this value.
+     *
+     * @return float value. 1 - means standard monitor, 2 and high - "retina" display.
+     */
+    public static float getPixelDensity() {
+        int pixelPerInch = getScreenDPI();
+        return (float) (pixelPerInch / 96.);
+    }
+
+    /**
+     * Check if a high DPI resolution is used
+     * @return <code>true</code> for HIDPI screens
+     */
+    public static boolean isHiDPI() {
+        return getPixelDensity() >= 2f;
+    }
+
+    /**
+     * Returns a resolution adapted size
+     * @param dim Size value to adapt (base size is a low DPI screen)
+     * @return adapted size (may be unmodified)
+     */
+    public static int getSizeDpiAdjusted(int size) {
+        if (size <= 0) return size;
+        int pixelPerInch = getScreenDPI();
+        return size * pixelPerInch / 96;
+    }
+
+    /**
+     * Returns a resolution adapted size
+     * @param dim Size value to adapt (base size is a low DPI screen)
+     * @return adapted size (may be unmodified)
+     */
+    public static float getSizeDpiAdjusted(float size) {
+        if (size <= 0f) return size;
+        int pixelPerInch = getScreenDPI();
+        return size * pixelPerInch / 96;
+    }
+
+    /**
+     * Returns a resolution adapted size
+     * @param dim Size value to adapt (base size is a low DPI screen)
+     * @return adapted size (may be unmodified)
+     */
+    public static double getSizeDpiAdjusted(double size) {
+        if (size <= 0d) return size;
+        int pixelPerInch = getScreenDPI();
+        return size * pixelPerInch / 96;
+    }
+
+    /**
+     * Returns a resolution adapted Dimension
+     * @param dim Dimension value to adapt (base size is a low DPI screen)
+     * @return adapted dimension (may be unmodified)
+     */
+    public static Dimension getDimensionDpiAdjusted(Dimension dim) {
+        int pixelPerInch = getScreenDPI();
+        int width = dim.width, height = dim.height;
+        if (dim.width > 0) {
+            width = dim.width * pixelPerInch / 96;
+        }
+
+        if (dim.height > 0) {
+            height = dim.height * pixelPerInch / 96;
+        }
+
+        return new Dimension(width, height);
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java	(revision 10358)
@@ -180,5 +180,5 @@
             mi.setText(label);
             if (iconName != null && Main.pref.getBoolean("text.popupmenu.useicons", true)) {
-                ImageIcon icon = new ImageProvider(iconName).setWidth(16).get();
+                ImageIcon icon = new ImageProvider(iconName).setSize(ImageProvider.ImageSizes.SMALLICON).get();
                 if (icon != null) {
                     mi.setIcon(icon);
Index: /trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 10358)
@@ -4,6 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Image;
-import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FileInputStream;
@@ -77,5 +75,5 @@
     public String iconPath;
     /** The plugin icon. */
-    public ImageIcon icon;
+    private ImageProvider icon;
     /** Plugin can be loaded at any time and not just at start. */
     public boolean canloadatruntime;
@@ -84,6 +82,6 @@
     /** All manifest attributes. */
     public final Map<String, String> attr = new TreeMap<>();
-
-    private static final ImageIcon emptyIcon = new ImageIcon(new BufferedImage(24, 24, BufferedImage.TYPE_INT_ARGB));
+    /** Empty icon for these plugins which have none */
+    private static final ImageIcon emptyIcon = ImageProvider.getEmpty(ImageProvider.ImageSizes.LARGEICON);
 
     /**
@@ -244,7 +242,7 @@
             if (file != null) {
                 // extract icon from the plugin jar file
-                icon = new ImageProvider(iconPath).setArchive(file).setMaxWidth(24).setMaxHeight(24).setOptional(true).get();
+                icon = new ImageProvider(iconPath).setArchive(file).setMaxSize(ImageProvider.ImageSizes.LARGEICON).setOptional(true);
             } else if (iconPath.startsWith("data:")) {
-                icon = new ImageProvider(iconPath).setMaxWidth(24).setMaxHeight(24).setOptional(true).get();
+                icon = new ImageProvider(iconPath).setMaxSize(ImageProvider.ImageSizes.LARGEICON).setOptional(true);
             }
         }
@@ -494,11 +492,12 @@
 
     /**
-     * Replies the plugin icon, scaled to 24x24 pixels.
-     * @return the plugin icon, scaled to 24x24 pixels.
+     * Replies the plugin icon, scaled to LARGE_ICON size.
+     * @return the plugin icon, scaled to LARGE_ICON size.
      */
     public ImageIcon getScaledIcon() {
-        if (icon == null)
+        ImageIcon img = (icon != null) ? icon.get() : null;
+        if (img == null)
             return emptyIcon;
-        return new ImageIcon(icon.getImage().getScaledInstance(24, 24, Image.SCALE_SMOOTH));
+        return img;
     }
 
Index: /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 10358)
@@ -69,4 +69,5 @@
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
+import org.openstreetmap.josm.gui.util.GuiSizesHelper;
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.plugins.PluginHandler;
@@ -145,11 +146,11 @@
         CURSOR(Main.pref.getInteger("iconsize.cursor", 32)),
         /** cursor overlay icon size */
-        CURSOROVERLAY(CURSOR.imageSize),
+        CURSOROVERLAY(CURSOR),
         /** menu icon size */
-        MENU(SMALLICON.imageSize),
+        MENU(SMALLICON),
         /** menu icon size in popup menus
          * @since 8323
          */
-        POPUPMENU(LARGEICON.imageSize),
+        POPUPMENU(LARGEICON),
         /** Layer list icon size
          * @since 8323
@@ -159,28 +160,62 @@
          * @since 9253
          */
-        TOOLBAR(LARGEICON.imageSize),
+        TOOLBAR(LARGEICON),
         /** Side button maximum height
          * @since 9253
          */
         SIDEBUTTON(Main.pref.getInteger("iconsize.sidebutton", 20)),
+        /** Settings tab icon size
+         * @since 9253
+         */
+        SETTINGS_TAB(Main.pref.getInteger("iconsize.settingstab", 48)),
         /**
          * The default image size
          * @since 9705
          */
-        DEFAULT(Main.pref.getInteger("iconsize.default", 24));
-
-        private final int imageSize;
+        DEFAULT(Main.pref.getInteger("iconsize.default", 24)),
+        /**
+         * Splash dialog logo size
+         * @since 10358
+         */
+        SPLASH_LOGO(128, 129),
+        /**
+         * About dialog logo size
+         * @since 10358
+         */
+        ABOUT_LOGO(256, 258);
+
+        private final int virtualWidth;
+        private final int virtualHeight;
 
         ImageSizes(int imageSize) {
-            this.imageSize = imageSize;
+            this.virtualWidth = imageSize;
+            this.virtualHeight = imageSize;
+        }
+
+        ImageSizes(int width, int height) {
+            this.virtualWidth = width;
+            this.virtualHeight = height;
+        }
+
+        ImageSizes(ImageSizes that) {
+            this.virtualWidth = that.virtualWidth;
+            this.virtualHeight = that.virtualHeight;
         }
 
         /**
-         * Returns the image size in pixels
-         * @return the image size in pixels
+         * Returns the image width in virtual pixels
+         * @return the image width in virtual pixels
+         */
+        public int getVirtualWidth() {
+            return virtualWidth;
+        }
+
+        /**
+         * Returns the image height in virtual pixels
+         * @return the image height in virtual pixels
          * @since 9705
          */
-        public int getImageSize() {
-            return imageSize;
+        public int getVirtualHeight() {
+            return virtualHeight;
         }
 
@@ -191,5 +226,5 @@
          */
         public Dimension getImageDimension() {
-            return new Dimension(imageSize, imageSize);
+            return new Dimension(virtualWidth, virtualHeight);
         }
     }
@@ -219,12 +254,12 @@
     /** directory inside the archive */
     protected String inArchiveDir;
-    /** width of the resulting image, -1 when original image data should be used */
-    protected int width = -1;
-    /** height of the resulting image, -1 when original image data should be used */
-    protected int height = -1;
-    /** maximum width of the resulting image, -1 for no restriction */
-    protected int maxWidth = -1;
-    /** maximum height of the resulting image, -1 for no restriction */
-    protected int maxHeight = -1;
+    /** virtual width of the resulting image, -1 when original image data should be used */
+    protected int virtualWidth = -1;
+    /** virtual height of the resulting image, -1 when original image data should be used */
+    protected int virtualHeight = -1;
+    /** virtual maximum width of the resulting image, -1 for no restriction */
+    protected int virtualMaxWidth = -1;
+    /** virtual maximum height of the resulting image, -1 for no restriction */
+    protected int virtualMaxHeight = -1;
     /** In case of errors do not throw exception but return <code>null</code> for missing image */
     protected boolean optional;
@@ -306,8 +341,8 @@
         this.archive = image.archive;
         this.inArchiveDir = image.inArchiveDir;
-        this.width = image.width;
-        this.height = image.height;
-        this.maxWidth = image.maxWidth;
-        this.maxHeight = image.maxHeight;
+        this.virtualWidth = image.virtualWidth;
+        this.virtualHeight = image.virtualHeight;
+        this.virtualMaxWidth = image.virtualMaxWidth;
+        this.virtualMaxHeight = image.virtualMaxHeight;
         this.optional = image.optional;
         this.suppressWarnings = image.suppressWarnings;
@@ -389,6 +424,6 @@
      */
     public ImageProvider setSize(Dimension size) {
-        this.width = size.width;
-        this.height = size.height;
+        this.virtualWidth = size.width;
+        this.virtualHeight = size.height;
         return this;
     }
@@ -407,4 +442,18 @@
 
     /**
+     * Set the dimensions of the image.
+     *
+     * @param width final width of the image
+     * @param height final height of the image
+     * @return the current object, for convenience
+     * @since 10358
+     */
+    public ImageProvider setSize(int width, int height) {
+        this.virtualWidth = width;
+        this.virtualHeight = height;
+        return this;
+    }
+
+    /**
      * Set image width
      * @param width final width of the image
@@ -413,5 +462,5 @@
      */
     public ImageProvider setWidth(int width) {
-        this.width = width;
+        this.virtualWidth = width;
         return this;
     }
@@ -424,5 +473,5 @@
      */
     public ImageProvider setHeight(int height) {
-        this.height = height;
+        this.virtualHeight = height;
         return this;
     }
@@ -439,6 +488,6 @@
      */
     public ImageProvider setMaxSize(Dimension maxSize) {
-        this.maxWidth = maxSize.width;
-        this.maxHeight = maxSize.height;
+        this.virtualMaxWidth = maxSize.width;
+        this.virtualMaxHeight = maxSize.height;
         return this;
     }
@@ -458,9 +507,9 @@
      */
     public ImageProvider resetMaxSize(Dimension maxSize) {
-        if (this.maxWidth == -1 || maxSize.width < this.maxWidth) {
-            this.maxWidth = maxSize.width;
-        }
-        if (this.maxHeight == -1 || maxSize.height < this.maxHeight) {
-            this.maxHeight = maxSize.height;
+        if (this.virtualMaxWidth == -1 || maxSize.width < this.virtualMaxWidth) {
+            this.virtualMaxWidth = maxSize.width;
+        }
+        if (this.virtualMaxHeight == -1 || maxSize.height < this.virtualMaxHeight) {
+            this.virtualMaxHeight = maxSize.height;
         }
         return this;
@@ -498,5 +547,5 @@
      */
     public ImageProvider setMaxWidth(int maxWidth) {
-        this.maxWidth = maxWidth;
+        this.virtualMaxWidth = maxWidth;
         return this;
     }
@@ -509,5 +558,5 @@
      */
     public ImageProvider setMaxHeight(int maxHeight) {
-        this.maxHeight = maxHeight;
+        this.virtualMaxHeight = maxHeight;
         return this;
     }
@@ -557,8 +606,8 @@
         if (ir == null)
             return null;
-        if (maxWidth != -1 || maxHeight != -1)
-            return ir.getImageIconBounded(new Dimension(maxWidth, maxHeight));
+        if (virtualMaxWidth != -1 || virtualMaxHeight != -1)
+            return ir.getImageIconBounded(new Dimension(virtualMaxWidth, virtualMaxHeight));
         else
-            return ir.getImageIcon(new Dimension(width, height));
+            return ir.getImageIcon(new Dimension(virtualWidth, virtualHeight));
     }
 
@@ -656,4 +705,17 @@
 
     /**
+     * Load an empty image with a given size.
+     *
+     * @param size Target icon size
+     * @return The requested Image.
+     * @since 10358
+     */
+    public static ImageIcon getEmpty(ImageSizes size) {
+        Dimension iconRealSize = GuiSizesHelper.getDimensionDpiAdjusted(size.getImageDimension());
+        return new ImageIcon(new BufferedImage(iconRealSize.width, iconRealSize.height,
+            BufferedImage.TYPE_INT_ARGB));
+    }
+
+    /**
      * Load an image with a given file name.
      *
@@ -689,4 +751,20 @@
     public static ImageIcon getIfAvailable(String name) {
         return new ImageProvider(name).setOptional(true).get();
+    }
+
+    /**
+     * Scale image to virtual dimensions. This util method is used to hide real sizes calculations.
+     * All other classes should use this method to resize images.
+     *
+     * @param im image to be resized
+     * @param virtualWidth target width of image in virtual pixels
+     * @param virtualHeight target height of image in virtual pixels
+     * @return new scaled image in real dimensions
+     */
+    public static ImageIcon getScaledIcon(Image im, int virtualWidth, int virtualHeight) {
+        int realWidth = GuiSizesHelper.getSizeDpiAdjusted(virtualWidth);
+        int realHeight = GuiSizesHelper.getSizeDpiAdjusted(virtualHeight);
+
+        return new ImageIcon(im.getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH));
     }
 
@@ -1333,12 +1411,12 @@
                     MapImage icon = nodeStyle.mapImage;
                     if (icon != null) {
-                        int backgroundWidth = iconSize.width;
-                        int backgroundHeight = iconSize.height;
-                        int iconWidth = icon.getWidth();
-                        int iconHeight = icon.getHeight();
-                        BufferedImage image = new BufferedImage(backgroundWidth, backgroundHeight,
+                        int backgroundRealWidth = GuiSizesHelper.getSizeDpiAdjusted(iconSize.width);
+                        int backgroundRealHeight = GuiSizesHelper.getSizeDpiAdjusted(iconSize.height);
+                        int iconRealWidth = icon.getWidth();
+                        int iconRealHeight = icon.getHeight();
+                        BufferedImage image = new BufferedImage(backgroundRealWidth, backgroundRealHeight,
                                 BufferedImage.TYPE_INT_ARGB);
-                        double scaleFactor = Math.min(backgroundWidth / (double) iconWidth, backgroundHeight
-                                / (double) iconHeight);
+                        double scaleFactor = Math.min(backgroundRealWidth / (double) iconRealWidth, backgroundRealHeight
+                                / (double) iconRealHeight);
                         BufferedImage iconImage = icon.getImage(false);
                         Image scaledIcon;
@@ -1347,15 +1425,15 @@
                         if (scaleFactor < 1) {
                             // Scale icon such that it fits on background.
-                            scaledWidth = (int) (iconWidth * scaleFactor);
-                            scaledHeight = (int) (iconHeight * scaleFactor);
+                            scaledWidth = (int) (iconRealWidth * scaleFactor);
+                            scaledHeight = (int) (iconRealHeight * scaleFactor);
                             scaledIcon = iconImage.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH);
                         } else {
                             // Use original size, don't upscale.
-                            scaledWidth = iconWidth;
-                            scaledHeight = iconHeight;
+                            scaledWidth = iconRealWidth;
+                            scaledHeight = iconRealHeight;
                             scaledIcon = iconImage;
                         }
-                        image.getGraphics().drawImage(scaledIcon, (backgroundWidth - scaledWidth) / 2,
-                                (backgroundHeight - scaledHeight) / 2, null);
+                        image.getGraphics().drawImage(scaledIcon, (backgroundRealWidth - scaledWidth) / 2,
+                                (backgroundRealHeight - scaledHeight) / 2, null);
 
                         return new ImageIcon(image);
@@ -1394,33 +1472,35 @@
      */
     public static BufferedImage createImageFromSvg(SVGDiagram svg, Dimension dim) {
-        float realWidth = svg.getWidth();
-        float realHeight = svg.getHeight();
-        int width = Math.round(realWidth);
-        int height = Math.round(realHeight);
-        Double scaleX = null, scaleY = null;
+        float sourceWidth = svg.getWidth();
+        float sourceHeight = svg.getHeight();
+        int realWidth = Math.round(GuiSizesHelper.getSizeDpiAdjusted(sourceWidth));
+        int realHeight = Math.round(GuiSizesHelper.getSizeDpiAdjusted(sourceHeight));
+        Double scaleX, scaleY;
         if (dim.width != -1) {
-            width = dim.width;
-            scaleX = (double) width / realWidth;
+            realWidth = dim.width;
+            scaleX = (double) realWidth / sourceWidth;
             if (dim.height == -1) {
                 scaleY = scaleX;
-                height = (int) Math.round(realHeight * scaleY);
+                realHeight = (int) Math.round(sourceHeight * scaleY);
             } else {
-                height = dim.height;
-                scaleY = (double) height / realHeight;
+                realHeight = dim.height;
+                scaleY = (double) realHeight / sourceHeight;
             }
         } else if (dim.height != -1) {
-            height = dim.height;
-            scaleX = scaleY = (double) height / realHeight;
-            width = (int) Math.round(realWidth * scaleX);
-        }
-        if (width == 0 || height == 0) {
+            realHeight = dim.height;
+            scaleX = scaleY = (double) realHeight / sourceHeight;
+            realWidth = (int) Math.round(sourceWidth * scaleX);
+        }
+        else {
+            scaleX = scaleY = (double) realHeight / sourceHeight;
+        }
+
+        if (realWidth == 0 || realHeight == 0) {
             return null;
         }
-        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        BufferedImage img = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
         Graphics2D g = img.createGraphics();
-        g.setClip(0, 0, width, height);
-        if (scaleX != null && scaleY != null) {
-            g.scale(scaleX, scaleY);
-        }
+        g.setClip(0, 0, realWidth, realHeight);
+        g.scale(scaleX, scaleY);
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         try {
Index: /trunk/src/org/openstreetmap/josm/tools/ImageResource.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/ImageResource.java	(revision 10357)
+++ /trunk/src/org/openstreetmap/josm/tools/ImageResource.java	(revision 10358)
@@ -14,4 +14,5 @@
 
 import com.kitfox.svg.SVGDiagram;
+import org.openstreetmap.josm.gui.util.GuiSizesHelper;
 
 /**
@@ -50,5 +51,27 @@
         CheckParameterUtil.ensureParameterNotNull(img);
         this.baseImage = img;
+
+        img = scaleBaseImageIfNeeded(img);
+
         imgCache.put(DEFAULT_DIMENSION, img);
+    }
+
+    /** Scale image according to screen DPI if needed.
+     *
+     * @param img an image loaded from file (it's width and height are virtual pixels)
+     * @return original img if virtual size is the same as real size or new image resized to real pixels
+     */
+    private static Image scaleBaseImageIfNeeded(Image img) {
+        int imgWidth = img.getWidth(null);
+        int imgHeight = img.getHeight(null);
+        int realWidth = GuiSizesHelper.getSizeDpiAdjusted(imgWidth);
+        int realHeight = GuiSizesHelper.getSizeDpiAdjusted(imgHeight);
+        if (realWidth != -1 && realHeight != -1 && imgWidth != realWidth && imgHeight != realHeight) {
+            Image realImage = img.getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH);
+            BufferedImage bimg = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
+            bimg.getGraphics().drawImage(realImage, 0, 0, null);
+            img = bimg;
+        }
+        return img;
     }
 
@@ -88,7 +111,10 @@
      */
     public void getImageIcon(AbstractAction a) {
-        ImageIcon icon = getImageIconBounded(ImageProvider.ImageSizes.SMALLICON.getImageDimension());
+        Dimension iconDimension = ImageProvider.ImageSizes.SMALLICON.getImageDimension();
+        ImageIcon icon = getImageIconBounded(iconDimension);
         a.putValue(Action.SMALL_ICON, icon);
-        icon = getImageIconBounded(ImageProvider.ImageSizes.LARGEICON.getImageDimension());
+
+        iconDimension = ImageProvider.ImageSizes.LARGEICON.getImageDimension();
+        icon = getImageIconBounded(iconDimension);
         a.putValue(Action.LARGE_ICON_KEY, icon);
         a.putValue("ImageResource", this);
@@ -123,5 +149,6 @@
         }
         if (svg != null) {
-            BufferedImage bimg = ImageProvider.createImageFromSvg(svg, dim);
+            Dimension realDim = GuiSizesHelper.getDimensionDpiAdjusted(dim);
+            BufferedImage bimg = ImageProvider.createImageFromSvg(svg, realDim);
             if (bimg == null) {
                 return null;
@@ -137,17 +164,17 @@
             if (baseImage == null) throw new AssertionError();
 
-            int width = dim.width;
-            int height = dim.height;
+            int realWidth = GuiSizesHelper.getSizeDpiAdjusted(dim.width);
+            int realHeight = GuiSizesHelper.getSizeDpiAdjusted(dim.height);
             ImageIcon icon = new ImageIcon(baseImage);
-            if (width == -1 && height == -1) {
-                width = icon.getIconWidth();
-                height = icon.getIconHeight();
-            } else if (width == -1) {
-                width = Math.max(1, icon.getIconWidth() * height / icon.getIconHeight());
-            } else if (height == -1) {
-                height = Math.max(1, icon.getIconHeight() * width / icon.getIconWidth());
-            }
-            Image i = icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH);
-            BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+            if (realWidth == -1 && realHeight == -1) {
+                realWidth = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconWidth());
+                realHeight = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconHeight());
+            } else if (realWidth == -1) {
+                realWidth = Math.max(1, icon.getIconWidth() * realHeight / icon.getIconHeight());
+            } else if (realHeight == -1) {
+                realHeight = Math.max(1, icon.getIconHeight() * realWidth / icon.getIconWidth());
+            }
+            Image i = icon.getImage().getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH);
+            BufferedImage bimg = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
             bimg.getGraphics().drawImage(i, 0, 0, null);
             if (overlayInfo != null) {
@@ -172,20 +199,20 @@
         if (maxSize.width < -1 || maxSize.width == 0 || maxSize.height < -1 || maxSize.height == 0)
             throw new IllegalArgumentException(maxSize+" is invalid");
-        float realWidth;
-        float realHeight;
+        float sourceWidth;
+        float sourceHeight;
         int maxWidth = maxSize.width;
         int maxHeight = maxSize.height;
         if (svg != null) {
-            realWidth = svg.getWidth();
-            realHeight = svg.getHeight();
+            sourceWidth = svg.getWidth();
+            sourceHeight = svg.getHeight();
         } else {
             if (baseImage == null) throw new AssertionError();
             ImageIcon icon = new ImageIcon(baseImage);
-            realWidth = icon.getIconWidth();
-            realHeight = icon.getIconHeight();
-            if (realWidth <= maxWidth) {
+            sourceWidth = icon.getIconWidth();
+            sourceHeight = icon.getIconHeight();
+            if (sourceWidth <= maxWidth) {
                 maxWidth = -1;
             }
-            if (realHeight <= maxHeight) {
+            if (sourceHeight <= maxHeight) {
                 maxHeight = -1;
             }
@@ -198,5 +225,5 @@
         else if (maxHeight == -1)
             return getImageIcon(new Dimension(maxWidth, -1));
-        else if (realWidth / maxWidth > realHeight / maxHeight)
+        else if (sourceWidth / maxWidth > sourceHeight / maxHeight)
             return getImageIcon(new Dimension(maxWidth, -1));
         else
