001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer.imagery; 003 004import java.awt.image.BufferedImage; 005import java.util.Arrays; 006import java.util.List; 007import java.util.concurrent.CopyOnWriteArrayList; 008 009import org.openstreetmap.josm.tools.ImageProcessor; 010 011/** 012 * This class holds the filter settings for an imagery. 013 * @author Michael Zangl 014 * @since 10547 015 */ 016public class ImageryFilterSettings implements ImageProcessor { 017 018 protected GammaImageProcessor gammaImageProcessor = new GammaImageProcessor(); 019 protected SharpenImageProcessor sharpenImageProcessor = new SharpenImageProcessor(); 020 protected ColorfulImageProcessor colorfulnessImageProcessor = new ColorfulImageProcessor(); 021 private final List<FilterChangeListener> filterChangeListeners = new CopyOnWriteArrayList<>(); 022 023 /** 024 * Returns the currently set gamma value. 025 * @return the currently set gamma value 026 */ 027 public double getGamma() { 028 return gammaImageProcessor.getGamma(); 029 } 030 031 /** 032 * Sets a new gamma value, {@code 1} stands for no correction. 033 * @param gamma new gamma value 034 */ 035 public void setGamma(double gamma) { 036 gammaImageProcessor.setGamma(gamma); 037 fireListeners(); 038 } 039 040 /** 041 * Gets the current sharpen level. 042 * @return The sharpen level. 043 */ 044 public double getSharpenLevel() { 045 return sharpenImageProcessor.getSharpenLevel(); 046 } 047 048 /** 049 * Sets the sharpen level for the imagery. 050 * <code>1</code> means no change in sharpness. 051 * Values in range 0..1 blur the image. 052 * Values above 1 are used to sharpen the image. 053 * @param sharpenLevel The sharpen level. 054 */ 055 public void setSharpenLevel(double sharpenLevel) { 056 sharpenImageProcessor.setSharpenLevel((float) sharpenLevel); 057 fireListeners(); 058 } 059 060 /** 061 * Gets the colorfulness of this image. 062 * @return The colorfulness 063 */ 064 public double getColorfulness() { 065 return colorfulnessImageProcessor.getColorfulness(); 066 } 067 068 /** 069 * Sets the colorfulness of this image. 070 * 0 means grayscale. 071 * 1 means normal colorfulness. 072 * Values greater than 1 are allowed. 073 * @param colorfulness The colorfulness. 074 */ 075 public void setColorfulness(double colorfulness) { 076 colorfulnessImageProcessor.setColorfulness(colorfulness); 077 fireListeners(); 078 } 079 080 /** 081 * Gets the image processors for this setting. 082 * @return The processors in the order in which they should be applied. 083 */ 084 public List<ImageProcessor> getProcessors() { 085 return Arrays.asList(colorfulnessImageProcessor, gammaImageProcessor, sharpenImageProcessor); 086 } 087 088 @Override 089 public BufferedImage process(BufferedImage image) { 090 for (ImageProcessor processor : getProcessors()) { 091 image = processor.process(image); 092 } 093 return image; 094 } 095 096 /** 097 * Adds a filter change listener 098 * @param l The listener 099 */ 100 public void addFilterChangeListener(FilterChangeListener l) { 101 filterChangeListeners.add(l); 102 } 103 104 /** 105 * Removes a filter change listener 106 * @param l The listener 107 */ 108 public void removeFilterChangeListener(FilterChangeListener l) { 109 filterChangeListeners.remove(l); 110 } 111 112 private void fireListeners() { 113 for (FilterChangeListener l : filterChangeListeners) { 114 l.filterChanged(); 115 } 116 } 117 118 /** 119 * A listener that listens to filter changes 120 * @author Michael Zangl 121 * @since 10600 (functional interface) 122 */ 123 @FunctionalInterface 124 public interface FilterChangeListener { 125 /** 126 * Invoked when the filter is changed. 127 */ 128 void filterChanged(); 129 } 130}