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}