[10547] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.gui.layer.imagery;
|
---|
| 3 |
|
---|
| 4 | import java.awt.image.BufferedImage;
|
---|
| 5 | import java.awt.image.ConvolveOp;
|
---|
| 6 | import java.awt.image.Kernel;
|
---|
| 7 |
|
---|
| 8 | import org.openstreetmap.josm.gui.layer.ImageProcessor;
|
---|
| 9 |
|
---|
| 10 | /**
|
---|
| 11 | * Sharpens or blurs the image, depending on the sharpen value.
|
---|
| 12 | * <p>
|
---|
| 13 | * A positive sharpen level means that we sharpen the image.
|
---|
| 14 | * <p>
|
---|
| 15 | * A negative sharpen level let's us blur the image. -1 is the most useful value there.
|
---|
| 16 | *
|
---|
| 17 | * @author Michael Zangl
|
---|
| 18 | * @since 10547
|
---|
| 19 | */
|
---|
| 20 | public class SharpenImageProcessor implements ImageProcessor {
|
---|
| 21 | private float sharpenLevel = 1;
|
---|
| 22 | private ConvolveOp op;
|
---|
| 23 |
|
---|
| 24 | private static float[] KERNEL_IDENTITY = new float[] {
|
---|
| 25 | 0, 0, 0,
|
---|
| 26 | 0, 1, 0,
|
---|
| 27 | 0, 0, 0
|
---|
| 28 | };
|
---|
| 29 |
|
---|
| 30 | private static float[] KERNEL_BLUR = new float[] {
|
---|
| 31 | 1f / 16, 2f / 16, 1f / 16,
|
---|
| 32 | 2f / 16, 4f / 16, 2f / 16,
|
---|
| 33 | 1f / 16, 2f / 16, 1f / 16
|
---|
| 34 | };
|
---|
| 35 |
|
---|
| 36 | private static float[] KERNEL_SHARPEN = new float[] {
|
---|
| 37 | -.5f, -1f, -.5f,
|
---|
| 38 | -1f, 7, -1f,
|
---|
| 39 | -.5f, -1f, -.5f
|
---|
| 40 | };
|
---|
| 41 |
|
---|
| 42 | /**
|
---|
| 43 | * Gets the current sharpen level.
|
---|
| 44 | * @return The level.
|
---|
| 45 | */
|
---|
| 46 | public float getSharpenLevel() {
|
---|
| 47 | return sharpenLevel;
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | /**
|
---|
| 51 | * Sets the sharpening level.
|
---|
| 52 | * @param sharpenLevel The level. Clamped to be positive or 0.
|
---|
| 53 | */
|
---|
| 54 | public void setSharpenLevel(float sharpenLevel) {
|
---|
| 55 | if (sharpenLevel < 0) {
|
---|
| 56 | this.sharpenLevel = 0;
|
---|
| 57 | } else {
|
---|
| 58 | this.sharpenLevel = sharpenLevel;
|
---|
| 59 | }
|
---|
| 60 |
|
---|
| 61 | if (this.sharpenLevel < 0.95) {
|
---|
| 62 | op = generateMixed(this.sharpenLevel, KERNEL_IDENTITY, KERNEL_BLUR);
|
---|
| 63 | } else if (this.sharpenLevel > 1.05) {
|
---|
| 64 | op = generateMixed(this.sharpenLevel - 1, KERNEL_SHARPEN, KERNEL_IDENTITY);
|
---|
| 65 | } else {
|
---|
| 66 | op = null;
|
---|
| 67 | }
|
---|
| 68 | }
|
---|
| 69 |
|
---|
[10755] | 70 | private static ConvolveOp generateMixed(float aFactor, float[] a, float[] b) {
|
---|
[10547] | 71 | if (a.length != 9 || b.length != 9) {
|
---|
| 72 | throw new IllegalArgumentException("Illegal kernel array length.");
|
---|
| 73 | }
|
---|
| 74 | float[] values = new float[9];
|
---|
| 75 | for (int i = 0; i < values.length; i++) {
|
---|
| 76 | values[i] = aFactor * a[i] + (1 - aFactor) * b[i];
|
---|
| 77 | }
|
---|
| 78 | return new ConvolveOp(new Kernel(3, 3, values), ConvolveOp.EDGE_NO_OP, null);
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | @Override
|
---|
| 82 | public BufferedImage process(BufferedImage image) {
|
---|
| 83 | if (op != null) {
|
---|
| 84 | return op.filter(image, null);
|
---|
| 85 | } else {
|
---|
| 86 | return image;
|
---|
| 87 | }
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | @Override
|
---|
| 91 | public String toString() {
|
---|
| 92 | return "SharpenImageProcessor [sharpenLevel=" + sharpenLevel + ']';
|
---|
| 93 | }
|
---|
| 94 | }
|
---|