Changeset 13397 in josm
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulFilter.java
r12620 r13397 11 11 import java.awt.image.DataBuffer; 12 12 import java.awt.image.DataBufferByte; 13 import java.awt.image.IndexColorModel; 14 import java.util.Objects; 13 15 import java.util.Optional; 16 import java.util.function.Consumer; 14 17 15 18 import org.openstreetmap.josm.tools.Logging; … … 20 23 */ 21 24 public class ColorfulFilter implements BufferedImageOp { 25 private static final double LUMINOSITY_RED = .21d; 26 private static final double LUMINOSITY_GREEN = .72d; 27 private static final double LUMINOSITY_BLUE = .07d; 22 28 private final double colorfulness; 23 29 … … 37 43 38 44 BufferedImage dest = Optional.ofNullable(dst).orElseGet(() -> createCompatibleDestImage(src, null)); 45 int type = src.getType(); 46 47 if (type == BufferedImage.TYPE_BYTE_INDEXED) { 48 return filterIndexed(src, dest); 49 } 50 39 51 DataBuffer srcBuffer = src.getRaster().getDataBuffer(); 40 52 DataBuffer destBuffer = dest.getRaster().getDataBuffer(); … … 44 56 } 45 57 46 int type = src.getType();47 58 if (type != dest.getType()) { 48 59 Logging.trace("Cannot apply color filter: Src / Dest differ in type (" + type + '/' + dest.getType() + ')'); … … 81 92 } 82 93 94 /** 95 * Fast alternative for indexed images: We can change the palette here. 96 * @param src The source image 97 * @param dest The image to copy the source to 98 * @return The image. 99 */ 100 private BufferedImage filterIndexed(BufferedImage src, BufferedImage dest) { 101 Objects.requireNonNull(dest, "dst needs to be non null"); 102 if (src.getType() != BufferedImage.TYPE_BYTE_INDEXED) { 103 throw new IllegalArgumentException("Source must be of type TYPE_BYTE_INDEXED"); 104 } 105 if (dest.getType() != BufferedImage.TYPE_BYTE_INDEXED) { 106 throw new IllegalArgumentException("Destination must be of type TYPE_BYTE_INDEXED"); 107 } 108 if (!(src.getColorModel() instanceof IndexColorModel)) { 109 throw new IllegalArgumentException("Expecting an IndexColorModel for a image of type TYPE_BYTE_INDEXED"); 110 } 111 src.copyData(dest.getRaster()); 112 113 IndexColorModel model = (IndexColorModel) src.getColorModel(); 114 int size = model.getMapSize(); 115 byte[] red = getIndexColorModelData(size, model::getReds); 116 byte[] green = getIndexColorModelData(size, model::getGreens); 117 byte[] blue = getIndexColorModelData(size, model::getBlues); 118 byte[] alphas = getIndexColorModelData(size, model::getAlphas); 119 120 for (int i = 0; i < size; i++) { 121 int r = red[i] & 0xff; 122 int g = green[i] & 0xff; 123 int b = blue[i] & 0xff; 124 double luminosity = r * LUMINOSITY_RED + g * LUMINOSITY_GREEN + b * LUMINOSITY_BLUE; 125 red[i] = mix(r, luminosity); 126 green[i] = mix(g, luminosity); 127 blue[i] = mix(b, luminosity); 128 } 129 130 IndexColorModel dstModel = new IndexColorModel(model.getPixelSize(), model.getMapSize(), red, green, blue, alphas); 131 return new BufferedImage(dstModel, dest.getRaster(), dest.isAlphaPremultiplied(), null); 132 } 133 134 private static byte[] getIndexColorModelData(int size, Consumer<byte[]> consumer) { 135 byte[] data = new byte[size]; 136 consumer.accept(data); 137 return data; 138 } 139 83 140 private void doFilter(DataBufferByte src, DataBufferByte dest, int redOffset, int greenOffset, int blueOffset, 84 141 int alphaOffset, boolean hasAlpha) { … … 94 151 int g = srcPixels[i + greenOffset] & 0xff; 95 152 int b = srcPixels[i + blueOffset] & 0xff; 96 double luminosity = r * .21d + g * .72d + b * .07d;153 double luminosity = r * LUMINOSITY_RED + g * LUMINOSITY_GREEN + b * LUMINOSITY_BLUE; 97 154 destPixels[i + redOffset] = mix(r, luminosity); 98 155 destPixels[i + greenOffset] = mix(g, luminosity); -
trunk/test/unit/org/openstreetmap/josm/gui/layer/imagery/ColorfulImageProcessorTest.java
r10547 r13397 8 8 import java.awt.Graphics2D; 9 9 import java.awt.image.BufferedImage; 10 import java.awt.image.DataBuffer; 11 import java.awt.image.IndexColorModel; 10 12 11 13 import org.junit.Rule; … … 22 24 23 25 private static final int TEST_IMAGE_SIZE = 5; 26 27 private static final int[] PALETTE = { 28 Color.BLACK.getRGB(), 29 Color.WHITE.getRGB(), 30 Color.GRAY.getRGB(), 31 Color.GREEN.getRGB(), 32 Color.RED.getRGB(), 33 Color.BLUE.getRGB(), 34 0xff908050, 35 0xff908070, 36 0xff908070, 37 0xff908070, 38 0xfff02080, 39 }; 40 41 private static final IndexColorModel COLOR_MODEL = new IndexColorModel(8, PALETTE.length, PALETTE, 0, true, 255, DataBuffer.TYPE_BYTE); 24 42 25 43 /** … … 79 97 BufferedImage.TYPE_3BYTE_BGR, 80 98 BufferedImage.TYPE_4BYTE_ABGR, 81 BufferedImage.TYPE_4BYTE_ABGR_PRE }) { 99 BufferedImage.TYPE_4BYTE_ABGR_PRE, 100 BufferedImage.TYPE_BYTE_INDEXED }) { 82 101 assertTrue(runProcessing(data, type)); 83 102 } … … 104 123 105 124 private BufferedImage createImage(Color color, int type) { 106 BufferedImage image = new BufferedImage(TEST_IMAGE_SIZE, TEST_IMAGE_SIZE, type); 125 BufferedImage image = type == BufferedImage.TYPE_BYTE_INDEXED 126 ? new BufferedImage(TEST_IMAGE_SIZE, TEST_IMAGE_SIZE, type, COLOR_MODEL) 127 : new BufferedImage(TEST_IMAGE_SIZE, TEST_IMAGE_SIZE, type); 107 128 Graphics2D graphics = image.createGraphics(); 108 129 graphics.setColor(color); 109 130 graphics.fillRect(0, 0, TEST_IMAGE_SIZE, TEST_IMAGE_SIZE); 131 assertEquals(color.getRGB(), image.getRGB(1, 1)); 110 132 return image; 111 133 }
Note:
See TracChangeset
for help on using the changeset viewer.