ColorUtil: fix modHSV, Color: HSV (#673)
This commit is contained in:
parent
2efa8808c0
commit
627a316e4d
@ -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));
|
||||
}
|
||||
}
|
||||
|
119
vtm-tests/test/org/oscim/utils/ColorTest.java
Normal file
119
vtm-tests/test/org/oscim/utils/ColorTest.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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() {
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user