001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.tools; 003 004import java.awt.Dimension; 005import java.awt.Image; 006import java.awt.image.BufferedImage; 007import java.util.List; 008 009import javax.swing.ImageIcon; 010 011/** class to describe how image overlay 012 * @since 8095 013 */ 014public class ImageOverlay implements ImageProcessor { 015 /** the image resource to use as overlay */ 016 public ImageProvider image; 017 /** offset of the image from left border, values between 0 and 1 */ 018 private final double offsetLeft; 019 /** offset of the image from top border, values between 0 and 1 */ 020 private final double offsetRight; 021 /** offset of the image from right border, values between 0 and 1*/ 022 private final double offsetTop; 023 /** offset of the image from bottom border, values between 0 and 1 */ 024 private final double offsetBottom; 025 026 /** 027 * Create an overlay info. All values are relative sizes between 0 and 1. Size of the image 028 * is the result of the difference between left/right and top/bottom. 029 * 030 * @param image image provider for the overlay icon 031 * @param offsetLeft offset of the image from left border, values between 0 and 1, -1 for auto-calculation 032 * @param offsetTop offset of the image from top border, values between 0 and 1, -1 for auto-calculation 033 * @param offsetRight offset of the image from right border, values between 0 and 1, -1 for auto-calculation 034 * @param offsetBottom offset of the image from bottom border, values between 0 and 1, -1 for auto-calculation 035 * @since 8095 036 */ 037 public ImageOverlay(ImageProvider image, double offsetLeft, double offsetTop, double offsetRight, double offsetBottom) { 038 this.image = image; 039 this.offsetLeft = offsetLeft; 040 this.offsetTop = offsetTop; 041 this.offsetRight = offsetRight; 042 this.offsetBottom = offsetBottom; 043 } 044 045 /** 046 * Create an overlay in southeast corner. All values are relative sizes between 0 and 1. 047 * Size of the image is the result of the difference between left/right and top/bottom. 048 * Right and bottom values are set to 1. 049 * 050 * @param image image provider for the overlay icon 051 * @see #ImageOverlay(ImageProvider, double, double, double, double) 052 * @since 8095 053 */ 054 public ImageOverlay(ImageProvider image) { 055 this.image = image; 056 this.offsetLeft = -1.0; 057 this.offsetTop = -1.0; 058 this.offsetRight = 1.0; 059 this.offsetBottom = 1.0; 060 } 061 062 /** 063 * Handle overlay. The image passed as argument is modified! 064 * 065 * @param ground the base image for the overlay (gets modified!) 066 * @return the modified image (same as argument) 067 * @since 8095 068 */ 069 @Override 070 public BufferedImage process(BufferedImage ground) { 071 return process(ground, false); 072 } 073 074 /** 075 * Handle overlay. The image passed as argument is modified! 076 * 077 * @param ground the base image for the overlay (gets modified!) 078 * @param highResolution whether the high resolution variant should be used to overlay 079 * @return the modified image (same as argument) 080 */ 081 BufferedImage process(BufferedImage ground, boolean highResolution) { 082 /* get base dimensions for calculation */ 083 int w = ground.getWidth(); 084 int h = ground.getHeight(); 085 int width = -1; 086 int height = -1; 087 if (offsetRight > 0 && offsetLeft > 0) { 088 width = (int) (w*(offsetRight-offsetLeft)); 089 } 090 if (offsetTop > 0 && offsetBottom > 0) { 091 height = (int) (h*(offsetBottom-offsetTop)); 092 } 093 image = new ImageProvider(image).setMaxSize(new Dimension(width, height)); 094 ImageIcon overlay = image.get(); 095 if (highResolution) { 096 List<Image> resolutionVariants = HiDPISupport.getResolutionVariants(overlay.getImage()); 097 if (resolutionVariants.size() >= 2) { 098 overlay = new ImageIcon(resolutionVariants.get(1)); 099 } 100 } 101 int x, y; 102 if (width == -1 && offsetLeft < 0) { 103 x = (int) (w*offsetRight) - overlay.getIconWidth(); 104 } else { 105 x = (int) (w*offsetLeft); 106 } 107 if (height == -1 && offsetTop < 0) { 108 y = (int) (h*offsetBottom) - overlay.getIconHeight(); 109 } else { 110 y = (int) (h*offsetTop); 111 } 112 overlay.paintIcon(null, ground.getGraphics(), x, y); 113 return ground; 114 } 115}