Changeset 16946 in josm for trunk/src/org/openstreetmap/josm/tools/ImageResource.java
- Timestamp:
- 2020-08-28T20:16:25+02:00 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/tools/ImageResource.java
r16926 r16946 29 29 30 30 /** 31 * Caches the image data for resized versions of the same image. 32 */ 33 private final Map< Dimension, BufferedImage> imgCache = new ConcurrentHashMap<>(4);31 * Caches the image data for resized versions of the same image. The key is obtained using {@link ImageResizeMode#cacheKey(Dimension)}. 32 */ 33 private final Map<Integer, BufferedImage> imgCache = new ConcurrentHashMap<>(4); 34 34 /** 35 35 * SVG diagram information in case of SVG vector image. … … 138 138 * to set the width, but otherwise scale the image proportionally. 139 139 * @return ImageIcon object for the image of this resource, scaled according to dim 140 * @see #getImageIconBounded(java.awt.Dimension , boolean)140 * @see #getImageIconBounded(java.awt.Dimension) 141 141 */ 142 142 public ImageIcon getImageIcon(Dimension dim) { 143 return getImageIcon(dim, true );143 return getImageIcon(dim, true, ImageResizeMode.AUTO); 144 144 } 145 145 … … 151 151 * (java.awt.image.MultiResolutionImage in Java 9), otherwise a plain {@link BufferedImage}. 152 152 * When running Java 8, this flag has no effect and a plain image will be returned in any case. 153 * @param resizeMode how to size/resize the image 153 154 * @return ImageIcon object for the image of this resource, scaled according to dim 154 155 * @since 12722 155 156 */ 156 ImageIcon getImageIcon(Dimension dim, boolean multiResolution ) {157 return getImageIconAlreadyScaled(GuiSizesHelper.getDimensionDpiAdjusted(dim), multiResolution, false );157 ImageIcon getImageIcon(Dimension dim, boolean multiResolution, ImageResizeMode resizeMode) { 158 return getImageIconAlreadyScaled(GuiSizesHelper.getDimensionDpiAdjusted(dim), multiResolution, false, resizeMode); 158 159 } 159 160 … … 167 168 * When running Java 8, this flag has no effect and a plain image will be returned in any case. 168 169 * @param highResolution whether the high resolution variant should be used for overlays 170 * @param resizeMode how to size/resize the image 169 171 * @return ImageIcon object for the image of this resource, scaled according to dim 170 172 */ 171 ImageIcon getImageIconAlreadyScaled(Dimension dim, boolean multiResolution, boolean highResolution ) {173 ImageIcon getImageIconAlreadyScaled(Dimension dim, boolean multiResolution, boolean highResolution, ImageResizeMode resizeMode) { 172 174 CheckParameterUtil.ensureThat((dim.width > 0 || dim.width == -1) && (dim.height > 0 || dim.height == -1), 173 175 () -> dim + " is invalid"); 174 176 175 BufferedImage img = imgCache.get(dim); 177 final int cacheKey = resizeMode.cacheKey(dim); 178 BufferedImage img = imgCache.get(cacheKey); 176 179 if (img == null) { 177 180 if (svg != null) { 178 img = ImageProvider.createImageFromSvg(svg, dim );181 img = ImageProvider.createImageFromSvg(svg, dim, resizeMode); 179 182 if (img == null) { 180 183 return null; … … 182 185 } else { 183 186 if (baseImage == null) throw new AssertionError(); 184 185 187 ImageIcon icon = new ImageIcon(baseImage); 186 if (dim.width == -1 && dim.height == -1) { 187 dim.width = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconWidth()); 188 dim.height = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconHeight()); 189 } else if (dim.width == -1) { 190 dim.width = Math.max(1, icon.getIconWidth() * dim.height / icon.getIconHeight()); 191 } else if (dim.height == -1) { 192 dim.height = Math.max(1, icon.getIconHeight() * dim.width / icon.getIconWidth()); 193 } 194 Image i = icon.getImage().getScaledInstance(dim.width, dim.height, Image.SCALE_SMOOTH); 195 img = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB); 196 img.getGraphics().drawImage(i, 0, 0, null); 188 img = resizeMode.createBufferedImage(dim, new Dimension(icon.getIconWidth(), icon.getIconHeight()), 189 g -> g.drawImage(icon.getImage(), 0, 0, null)); 197 190 } 198 191 if (overlayInfo != null) { … … 212 205 disabledIcon.paintIcon(new JPanel(), img.getGraphics(), 0, 0); 213 206 } 214 imgCache.put( dim, img);207 imgCache.put(cacheKey, img); 215 208 } 216 209 … … 219 212 else { 220 213 try { 221 Image mrImg = HiDPISupport.getMultiResolutionImage(img, this );214 Image mrImg = HiDPISupport.getMultiResolutionImage(img, this, resizeMode); 222 215 return new ImageIcon(mrImg); 223 216 } catch (NoClassDefFoundError e) { … … 237 230 * which means it is not bounded. 238 231 * @return ImageIcon object for the image of this resource, scaled down if needed, according to maxSize 239 * @see #getImageIconBounded(java.awt.Dimension, boolean)240 232 */ 241 233 public ImageIcon getImageIconBounded(Dimension maxSize) { 242 return getImageIconBounded(maxSize, true); 243 } 244 245 /** 246 * Get image icon with a certain maximum size. The image is scaled down 247 * to fit maximum dimensions. (Keeps aspect ratio) 248 * 249 * @param maxSize The maximum size. One of the dimensions (width or height) can be -1, 250 * which means it is not bounded. 251 * @param multiResolution If true, return a multi-resolution image 252 * (java.awt.image.MultiResolutionImage in Java 9), otherwise a plain {@link BufferedImage}. 253 * When running Java 8, this flag has no effect and a plain image will be returned in any case. 254 * @return ImageIcon object for the image of this resource, scaled down if needed, according to maxSize 255 * @since 12722 256 */ 257 public ImageIcon getImageIconBounded(Dimension maxSize, boolean multiResolution) { 258 CheckParameterUtil.ensureThat((maxSize.width > 0 || maxSize.width == -1) && (maxSize.height > 0 || maxSize.height == -1), 259 () -> maxSize + " is invalid"); 260 float sourceWidth; 261 float sourceHeight; 262 int maxWidth = maxSize.width; 263 int maxHeight = maxSize.height; 264 if (svg != null) { 265 sourceWidth = svg.getWidth(); 266 sourceHeight = svg.getHeight(); 267 } else { 268 if (baseImage == null) throw new AssertionError(); 269 ImageIcon icon = new ImageIcon(baseImage); 270 sourceWidth = icon.getIconWidth(); 271 sourceHeight = icon.getIconHeight(); 272 if (sourceWidth <= maxWidth) { 273 maxWidth = -1; 274 } 275 if (sourceHeight <= maxHeight) { 276 maxHeight = -1; 277 } 278 } 279 280 if (maxWidth == -1 && maxHeight == -1) 281 return getImageIcon(DEFAULT_DIMENSION, multiResolution); 282 else if (maxWidth == -1) 283 return getImageIcon(new Dimension(-1, maxHeight), multiResolution); 284 else if (maxHeight == -1) 285 return getImageIcon(new Dimension(maxWidth, -1), multiResolution); 286 else if (sourceWidth / maxWidth > sourceHeight / maxHeight) 287 return getImageIcon(new Dimension(maxWidth, -1), multiResolution); 288 else 289 return getImageIcon(new Dimension(-1, maxHeight), multiResolution); 234 return getImageIcon(maxSize, true, ImageResizeMode.BOUNDED); 290 235 } 291 236 … … 297 242 */ 298 243 public ImageIcon getPaddedIcon(Dimension iconSize) { 299 final ImageIcon imageIcon = getImageIcon(iconSize); 300 if (imageIcon.getIconWidth() == iconSize.width && imageIcon.getIconHeight() == iconSize.height) { 301 // fast path for square and svg icons 302 return imageIcon; 303 } 304 305 final Dimension cacheKey = new Dimension(-iconSize.width, -iconSize.height); // use negative width/height for differentiation 306 BufferedImage image = imgCache.get(cacheKey); 307 if (image == null) { 308 image = ImageProvider.createPaddedIcon(getImageIcon().getImage(), iconSize); 309 imgCache.put(cacheKey, image); 310 } 311 return new ImageIcon(image); 244 return getImageIcon(iconSize, true, ImageResizeMode.PADDED); 312 245 } 313 246
Note:
See TracChangeset
for help on using the changeset viewer.