ColorUtil: fix modHSV, Color: HSV (#673)

This commit is contained in:
Gustl22 2019-02-23 01:38:33 +01:00 committed by Emux
parent 2efa8808c0
commit 627a316e4d
No known key found for this signature in database
GPG Key ID: 64ED9980896038C3
5 changed files with 183 additions and 21 deletions

View File

@ -7,6 +7,7 @@ import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.ToggleButton;
import org.oscim.backend.canvas.Color;
import org.oscim.layers.tile.buildings.BuildingLayer;
import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.layers.tile.vector.labeling.LabelLayer;
@ -24,9 +25,6 @@ import org.oscim.theme.styles.RenderStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.oscim.utils.ColorUtil.modHsv;
import static org.oscim.utils.ColorUtil.shiftHue;
public class ThemeStylerActivity extends BaseMapActivity implements OnSeekBarChangeListener {
final Logger log = LoggerFactory.getLogger(ThemeStylerActivity.class);
@ -90,13 +88,10 @@ public class ThemeStylerActivity extends BaseMapActivity implements OnSeekBarCha
}
int modColor(int color, HSV hsv) {
return modHsv(shiftHue(color, hsv.hue), 1, hsv.sat, hsv.val, true);
return hsv.mod(color, true);
}
public static class HSV {
public double hue = 0;
public double sat = 1;
public double val = 1;
public static class HSV extends Color.HSV {
public boolean changed;
}
@ -124,16 +119,16 @@ public class ThemeStylerActivity extends BaseMapActivity implements OnSeekBarCha
c = outlineColor;
if (id == R.id.seekBarS)
c.sat = progress / 50f;
c.saturation = progress / 50f;
else if (id == R.id.seekBarV)
c.val = progress / 50f;
c.value = progress / 50f;
else if (id == R.id.seekBarH)
c.hue = progress / 100f;
log.debug((modArea ? "area" : "line")
+ " h:" + c.hue
+ " s:" + c.sat
+ " v:" + c.val);
+ " s:" + c.saturation
+ " v:" + c.value);
VectorTileLayer l = (VectorTileLayer) mMap.layers().get(1);
RenderTheme t = (RenderTheme) l.getTheme();
@ -181,8 +176,8 @@ public class ThemeStylerActivity extends BaseMapActivity implements OnSeekBarCha
}
if (c == null)
return;
((SeekBar) findViewById(R.id.seekBarS)).setProgress((int) (c.sat * 50));
((SeekBar) findViewById(R.id.seekBarV)).setProgress((int) (c.val * 50));
((SeekBar) findViewById(R.id.seekBarS)).setProgress((int) (c.saturation * 50));
((SeekBar) findViewById(R.id.seekBarV)).setProgress((int) (c.value * 50));
((SeekBar) findViewById(R.id.seekBarH)).setProgress((int) (c.hue * 100));
}
}

View File

@ -0,0 +1,119 @@
/*
* Copyright 2019 Gustl22
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.utils;
import org.junit.Test;
import org.oscim.backend.canvas.Color;
import java.awt.Desktop;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.oscim.backend.canvas.Color.b;
import static org.oscim.backend.canvas.Color.g;
import static org.oscim.backend.canvas.Color.r;
public class ColorTest {
// See: https://en.wikipedia.org/wiki/ANSI_escape_code
public static final String ANSI_RESET = "\033[0m";
public static final String ANSI_PREFIX_BACKGROUND_24Bit = "\033[48;2;";
public static final String ANSI_PREFIX_FOREGROUND_24Bit = "\033[38;2;";
@Test
public void testColorHSV() {
List<Integer> colors = initHSVTest();
for (int color : colors) {
// Try to display them in terminal (Intellij not supports 24 bit colors)
System.out.println(ANSI_PREFIX_BACKGROUND_24Bit + Color.r(color) + ";" + Color.g(color) + ";" + Color.b(color) + "m "
+ Color.toString(color) + "\t" + (new Color.HSV(ColorUtil.rgbToHsv(r(color), g(color), b(color)))).toString()
+ ANSI_RESET);
}
}
public List<Integer> initHSVTest() {
List<Integer> colors = new ArrayList<>();
int color;
// Hue
color = Color.get(255, 0, 0);
colors.add(color);
colors.add(ColorUtil.modHsv(color, 0.33f, 1f, 1f, false));
color = Color.get(0, 0, 255);
colors.add(color);
colors.add(ColorUtil.modHsv(color, 0.33f, 1f, 1f, false));
// Saturation
color = Color.get(255, 200, 200);
colors.add(color);
colors.add(ColorUtil.modHsv(color, 0f, 1.5f, 1f, false));
color = Color.get(255, 0, 0);
colors.add(color);
colors.add(ColorUtil.modHsv(color, 0f, 0.5f, 1f, false));
// Lightness (value)
color = Color.get(255, 255, 255);
colors.add(color);
colors.add(ColorUtil.modHsv(color, 0f, 1f, 0.8f, false));
color = Color.get(0, 0, 0);
colors.add(color);
colors.add(ColorUtil.modHsv(color, 0f, 1f, 1.5f, false));
return colors;
}
private void displayHSVColorsInBrowser(List<Integer> colors) {
try {
File tempFile;
tempFile = File.createTempFile("test-color-", ".html");
tempFile.deleteOnExit();
StringBuilder builder = new StringBuilder("<html>");
for (int color : colors) {
builder.append(String.format("<div><pre style=\"background:rgb(%s,%s,%s);margin:0;\">", Color.r(color), Color.g(color), Color.b(color)));
builder.append(Color.toString(color));
builder.append("\t");
builder.append((new Color.HSV(ColorUtil.rgbToHsv(r(color), g(color), b(color)))).toString());
builder.append("</pre></div>");
}
builder.append("</html>");
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
writer.write(builder.toString());
writer.close();
Desktop.getDesktop().browse(tempFile.toURI());
Thread.sleep(2000);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ColorTest test = new ColorTest();
List<Integer> colors = test.initHSVTest();
test.displayHSVColorsInBrowser(colors);
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2018 Gustl22
* Copyright 2018-2019 Gustl22
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -18,10 +18,45 @@
package org.oscim.backend.canvas;
import org.oscim.utils.ColorUtil;
import org.oscim.utils.FastMath;
import org.oscim.utils.math.Vec3;
public final class Color {
public static class HSV {
public double hue;
public double saturation;
public double value;
public HSV() {
hue = 0;
saturation = 1;
value = 1;
}
public HSV(double hue, double saturation, double value) {
this.hue = hue;
this.saturation = saturation;
this.value = value;
}
public HSV(Vec3 hsv) {
hue = hsv.x;
saturation = hsv.y;
value = hsv.z;
}
public int mod(int color, boolean relative) {
return ColorUtil.modHsv(color, hue, saturation, value, relative);
}
@Override
public String toString() {
return "HSV: " + hue + ", " + saturation + ", " + value;
}
}
private static final int OPAQUE = 0xff000000;
public static int fadePremul(int color, double alpha) {
@ -262,6 +297,10 @@ public final class Color {
return (color & OPAQUE) == OPAQUE;
}
public static String toString(int color) {
return "RGB: " + Color.r(color) + ", " + Color.g(color) + ", " + Color.b(color);
}
private Color() {
}
}

View File

@ -212,7 +212,7 @@ public class MeshBucket extends RenderBucket {
int c = (ml.area == null) ? Color.BLUE : ml.area.color;
gl.lineWidth(1);
//c = ColorUtil.shiftHue(c, 0.5);
c = ColorUtil.modHsv(c, 1.1, 1.0, 0.8, true);
c = ColorUtil.modHsv(c, 0.1, 1.0, 0.8, true);
GLUtils.setColor(s.uColor, c, 1);
gl.drawElements(GL.LINES,
ml.numIndices,

View File

@ -63,19 +63,28 @@ public class ColorUtil {
}
/**
* @param hue the hue
* @param hue the hue from 0 to 1 (exclusive)
* 0: no color shift
* 0.5: opposite hue
* @param saturation the saturation
* @param value the lightness (usual a range from 0 to 2)
* 0 to 1: desaturate
* 1 to 2: saturate
* @param value the lightness
* 0 to 1: darken
* 1 to 2: lighten
* @param relative indicate if colors are modified relative to their values
* (e.g black not changes if relative)
*/
public static synchronized int modHsv(int color, double hue, double saturation, double value,
boolean relative) {
if ((hue == 0 || hue == 1) && saturation == 1 && value == 1)
return color;
Vec3 hsl = TMP_VEC;
rgbToHsv(r(color), g(color), b(color), hsl);
return hsvToRgb(clamp(hue * hsl.x, 0, 1),
clamp(saturation * hsl.y, 0, 1),
clamp(relative || (value - 1) < 0 ? value * hsl.z :
return hsvToRgb(clamp((hue + hsl.x) % 1, 0, 1),
clamp(relative || saturation <= 1 ? saturation * hsl.y :
hsl.y + (saturation - 1) * (1 - hsl.y), 0, 1),
clamp(relative || value <= 1 ? value * hsl.z :
hsl.z + (value - 1) * (1 - hsl.z), 0, 1));
}