Commit e4b3358f authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '1442-export-to-image' into 'devel_15.1.x'

neutral color is used in color extractor

See merge request !1264
parents 397db307 0cd0989f
Pipeline #36169 passed with stage
in 17 minutes and 40 seconds
...@@ -4,6 +4,8 @@ minerva (15.1.2) stable; urgency=medium ...@@ -4,6 +4,8 @@ minerva (15.1.2) stable; urgency=medium
* Bug fix: export to SBML failed if reactant/product line had length=0 * Bug fix: export to SBML failed if reactant/product line had length=0
* Bug fix: downloading submap from big project as a map quite often resulted * Bug fix: downloading submap from big project as a map quite often resulted
in error (#1440) in error (#1440)
* Bug fix: colors for values in exported image were incorrect for
intermediate values, like 0.5 (#1442)
-- Piotr Gawron <piotr.gawron@uni.lu> Thu, 7 Jan 2021 15:00:00 +0200 -- Piotr Gawron <piotr.gawron@uni.lu> Thu, 7 Jan 2021 15:00:00 +0200
......
...@@ -170,7 +170,7 @@ public abstract class AbstractImageGenerator { ...@@ -170,7 +170,7 @@ public abstract class AbstractImageGenerator {
this.level = params.getLevel(); this.level = params.getLevel();
this.scale = params.getScale(); this.scale = params.getScale();
colorExtractor = new ColorExtractor(params.getMinColor(), params.getMaxColor(), params.getSimpleColor()); colorExtractor = new ColorExtractor(params.getMinColor(), params.getMaxColor(), params.getSimpleColor(), params.getNeutralColor());
// set border frame extended by a margin // set border frame extended by a margin
border = new Rectangle2D.Double(params.getX() - SINGLE_FRAME_MARGIN, params.getY() - SINGLE_FRAME_MARGIN, border = new Rectangle2D.Double(params.getX() - SINGLE_FRAME_MARGIN, params.getY() - SINGLE_FRAME_MARGIN,
...@@ -383,7 +383,7 @@ public abstract class AbstractImageGenerator { ...@@ -383,7 +383,7 @@ public abstract class AbstractImageGenerator {
this.graphics = graphics; this.graphics = graphics;
} }
/** /**
* Saves generated image into file. * Saves generated image into file.
* *
* @param fileName * @param fileName
...@@ -400,7 +400,7 @@ public abstract class AbstractImageGenerator { ...@@ -400,7 +400,7 @@ public abstract class AbstractImageGenerator {
saveToFileImplementation(fileName); saveToFileImplementation(fileName);
} }
/** /**
* Saves generated image from {@link #getGraphics()} into file. * Saves generated image from {@link #getGraphics()} into file.
* *
* @param fileName * @param fileName
...@@ -700,6 +700,8 @@ public abstract class AbstractImageGenerator { ...@@ -700,6 +700,8 @@ public abstract class AbstractImageGenerator {
private Color simpleColor = Color.BLACK; private Color simpleColor = Color.BLACK;
private Color neutralColor = Color.WHITE;
/** /**
* @param scale * @param scale
* scale to set * scale to set
...@@ -1090,9 +1092,21 @@ public abstract class AbstractImageGenerator { ...@@ -1090,9 +1092,21 @@ public abstract class AbstractImageGenerator {
} }
public Params colorExtractor(ColorExtractor colorExtractor) { public Params colorExtractor(ColorExtractor colorExtractor) {
return minColor(colorExtractor.getMinColor()).maxColor(colorExtractor.getMaxColor()) return minColor(colorExtractor.getMinColor())
.simpleColor(colorExtractor.getSimpleColor()); .maxColor(colorExtractor.getMaxColor())
.simpleColor(colorExtractor.getSimpleColor())
.neutralColor(colorExtractor.getNeutralColor());
} }
public Params neutralColor(Color neutralColor) {
this.neutralColor = neutralColor;
return this;
}
public Color getNeutralColor() {
return this.neutralColor;
}
} }
} }
\ No newline at end of file
...@@ -48,8 +48,10 @@ public class ImageGenerators { ...@@ -48,8 +48,10 @@ public class ImageGenerators {
try { try {
availableGenerators = new ArrayList<Pair<String, Class<? extends AbstractImageGenerator>>>(); availableGenerators = new ArrayList<Pair<String, Class<? extends AbstractImageGenerator>>>();
Model model = new ModelFullIndexed(null); Model model = new ModelFullIndexed(null);
AbstractImageGenerator.Params params = new AbstractImageGenerator.Params().model(model).width(1) AbstractImageGenerator.Params params = new AbstractImageGenerator.Params().model(model).width(1).height(1)
.minColor(Color.WHITE).maxColor(Color.WHITE).height(1); .minColor(Color.WHITE)
.maxColor(Color.WHITE)
.neutralColor(Color.WHITE);
generatorInstances = new ArrayList<>(); generatorInstances = new ArrayList<>();
generatorInstances.add(new PngImageGenerator(params)); generatorInstances.add(new PngImageGenerator(params));
generatorInstances.add(new PdfImageGenerator(params)); generatorInstances.add(new PdfImageGenerator(params));
......
...@@ -25,7 +25,7 @@ public class ConverterTest extends GraphicsTestFunctions { ...@@ -25,7 +25,7 @@ public class ConverterTest extends GraphicsTestFunctions {
@Test @Test
public void test() { public void test() {
ColorExtractor colorExtractor = new ColorExtractor(Color.BLUE, Color.RED, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.BLUE, Color.RED, Color.BLUE, Color.WHITE);
new BioEntityConverterImpl(new BottomSquareCompartment("id1"), colorExtractor); new BioEntityConverterImpl(new BottomSquareCompartment("id1"), colorExtractor);
new BioEntityConverterImpl(new TopSquareCompartment("id2"), colorExtractor); new BioEntityConverterImpl(new TopSquareCompartment("id2"), colorExtractor);
new BioEntityConverterImpl(new LeftSquareCompartment("id3"), colorExtractor); new BioEntityConverterImpl(new LeftSquareCompartment("id3"), colorExtractor);
......
...@@ -27,7 +27,7 @@ import lcsb.mapviewer.model.map.species.GenericProtein; ...@@ -27,7 +27,7 @@ import lcsb.mapviewer.model.map.species.GenericProtein;
public class BioEntityConverterImplTest extends GraphicsTestFunctions { public class BioEntityConverterImplTest extends GraphicsTestFunctions {
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
@AfterClass @AfterClass
public static void tearDownAfterClass() throws Exception { public static void tearDownAfterClass() throws Exception {
......
...@@ -23,7 +23,7 @@ import lcsb.mapviewer.model.map.model.ModelFullIndexed; ...@@ -23,7 +23,7 @@ import lcsb.mapviewer.model.map.model.ModelFullIndexed;
public class PathwayCompartmentConverterTest extends GraphicsTestFunctions { public class PathwayCompartmentConverterTest extends GraphicsTestFunctions {
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
PathwayCompartmentConverter converter = new PathwayCompartmentConverter(colorExtractor); PathwayCompartmentConverter converter = new PathwayCompartmentConverter(colorExtractor);
@Test @Test
......
...@@ -25,7 +25,7 @@ public class SquareCompartmentConverterTest extends GraphicsTestFunctions { ...@@ -25,7 +25,7 @@ public class SquareCompartmentConverterTest extends GraphicsTestFunctions {
Logger logger = LogManager.getLogger(); Logger logger = LogManager.getLogger();
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
SquareCompartmentConverter converter = new SquareCompartmentConverter(colorExtractor); SquareCompartmentConverter converter = new SquareCompartmentConverter(colorExtractor);
@Test @Test
......
...@@ -22,7 +22,7 @@ public class ComplexConverterTest extends GraphicsTestFunctions { ...@@ -22,7 +22,7 @@ public class ComplexConverterTest extends GraphicsTestFunctions {
Logger logger = LogManager.getLogger(); Logger logger = LogManager.getLogger();
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); private ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
......
...@@ -21,7 +21,7 @@ import lcsb.mapviewer.model.map.species.field.StructuralState; ...@@ -21,7 +21,7 @@ import lcsb.mapviewer.model.map.species.field.StructuralState;
public class ComplexSbgnConverterTest extends GraphicsTestFunctions { public class ComplexSbgnConverterTest extends GraphicsTestFunctions {
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); private ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
@Test @Test
public void testDrawStructuralState() throws Exception { public void testDrawStructuralState() throws Exception {
......
...@@ -19,7 +19,7 @@ import lcsb.mapviewer.model.map.species.Protein; ...@@ -19,7 +19,7 @@ import lcsb.mapviewer.model.map.species.Protein;
public class ProteinConverterTest extends GraphicsTestFunctions { public class ProteinConverterTest extends GraphicsTestFunctions {
Logger logger = LogManager.getLogger(); Logger logger = LogManager.getLogger();
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
......
...@@ -20,7 +20,7 @@ import lcsb.mapviewer.model.map.species.field.StructuralState; ...@@ -20,7 +20,7 @@ import lcsb.mapviewer.model.map.species.field.StructuralState;
public class ProteinSbgnConverterTest extends GraphicsTestFunctions { public class ProteinSbgnConverterTest extends GraphicsTestFunctions {
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
@Test @Test
public void testDrawStructuralState() throws Exception { public void testDrawStructuralState() throws Exception {
......
...@@ -23,7 +23,7 @@ import lcsb.mapviewer.model.map.species.SimpleMolecule; ...@@ -23,7 +23,7 @@ import lcsb.mapviewer.model.map.species.SimpleMolecule;
public class SimpleMoleculeConverterTest extends GraphicsTestFunctions { public class SimpleMoleculeConverterTest extends GraphicsTestFunctions {
Logger logger = LogManager.getLogger(); Logger logger = LogManager.getLogger();
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
private BufferedImage bi; private BufferedImage bi;
private Graphics2D graphics; private Graphics2D graphics;
......
...@@ -21,7 +21,7 @@ import lcsb.mapviewer.model.map.species.SimpleMolecule; ...@@ -21,7 +21,7 @@ import lcsb.mapviewer.model.map.species.SimpleMolecule;
public class SimpleMoleculeSbgnConverterTest extends GraphicsTestFunctions { public class SimpleMoleculeSbgnConverterTest extends GraphicsTestFunctions {
Logger logger = LogManager.getLogger(); Logger logger = LogManager.getLogger();
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
private BufferedImage bi; private BufferedImage bi;
private Graphics2D graphics; private Graphics2D graphics;
......
...@@ -34,7 +34,7 @@ import lcsb.mapviewer.model.map.species.field.*; ...@@ -34,7 +34,7 @@ import lcsb.mapviewer.model.map.species.field.*;
public class SpeciesConverterTest extends GraphicsTestFunctions { public class SpeciesConverterTest extends GraphicsTestFunctions {
Logger logger = LogManager.getLogger(SpeciesConverterTest.class); Logger logger = LogManager.getLogger(SpeciesConverterTest.class);
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
......
...@@ -34,7 +34,7 @@ public class SpeciesGenericConverterTests extends GraphicsTestFunctions { ...@@ -34,7 +34,7 @@ public class SpeciesGenericConverterTests extends GraphicsTestFunctions {
Logger logger = LogManager.getLogger(); Logger logger = LogManager.getLogger();
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
private Element species; private Element species;
......
...@@ -34,7 +34,7 @@ import lcsb.mapviewer.model.map.species.GenericProtein; ...@@ -34,7 +34,7 @@ import lcsb.mapviewer.model.map.species.GenericProtein;
public class ReactionConverterTest extends GraphicsTestFunctions { public class ReactionConverterTest extends GraphicsTestFunctions {
ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE); ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE, Color.WHITE);
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
......
...@@ -28,7 +28,7 @@ public class ClearColorModelCommand extends ModelCommand { ...@@ -28,7 +28,7 @@ public class ClearColorModelCommand extends ModelCommand {
public ClearColorModelCommand(Model model) { public ClearColorModelCommand(Model model) {
super(model); super(model);
colorModelCommand = new ColorModelCommand(model, new ArrayList<>(), colorModelCommand = new ColorModelCommand(model, new ArrayList<>(),
new ColorExtractor(Color.WHITE, Color.WHITE, Color.WHITE)); new ColorExtractor(Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE));
} }
@Override @Override
......
package lcsb.mapviewer.commands; package lcsb.mapviewer.commands;
import java.awt.*; import java.awt.Color;
import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.layout.ColorSchema;
...@@ -20,12 +20,14 @@ public class ColorExtractor { ...@@ -20,12 +20,14 @@ public class ColorExtractor {
private Color minColor; private Color minColor;
/** /**
* Color that should be used for maxvalues of {@link ColorSchema#value}. * Color that should be used for max values of {@link ColorSchema#value}.
*/ */
private Color maxColor; private Color maxColor;
private Color simpleColor; private Color simpleColor;
private Color neutralColor;
/** /**
* Default constructor. * Default constructor.
* *
...@@ -36,13 +38,14 @@ public class ColorExtractor { ...@@ -36,13 +38,14 @@ public class ColorExtractor {
* Color that should be used for max values of * Color that should be used for max values of
* {@link ColorSchema#value} * {@link ColorSchema#value}
*/ */
public ColorExtractor(Color minColor, Color maxColor, Color simpleColor) { public ColorExtractor(Color minColor, Color maxColor, Color simpleColor, Color neutralColor) {
if (minColor == null || maxColor == null || simpleColor == null) { if (minColor == null || maxColor == null || simpleColor == null || neutralColor == null) {
throw new InvalidArgumentException("Parameters cannot be null"); throw new InvalidArgumentException("Parameters cannot be null");
} }
this.minColor = minColor; this.minColor = minColor;
this.maxColor = maxColor; this.maxColor = maxColor;
this.simpleColor = simpleColor; this.simpleColor = simpleColor;
this.neutralColor = neutralColor;
} }
/** /**
...@@ -72,17 +75,40 @@ public class ColorExtractor { ...@@ -72,17 +75,40 @@ public class ColorExtractor {
* @return color for the double value * @return color for the double value
*/ */
protected Color getColorForValue(Double value) { protected Color getColorForValue(Double value) {
int maxRed = maxColor.getRed();
int maxGreen = maxColor.getGreen();
int maxBlue = maxColor.getBlue();
int minRed = minColor.getRed();
int minGreen = minColor.getGreen();
int minBlue = minColor.getBlue();
int neutralRed = neutralColor.getRed();
int neutralGreen = neutralColor.getGreen();
int neutralBlue = neutralColor.getBlue();
if (value > 0) { if (value > 0) {
double ratio = value; double ratio = value;
return new Color((int) (maxColor.getRed() * ratio), (int) (maxColor.getGreen() * ratio), int red = getColorForRatio(neutralRed, maxRed, ratio);
(int) (maxColor.getBlue() * ratio)); int green = getColorForRatio(neutralGreen, maxGreen, ratio);
int blue = getColorForRatio(neutralBlue, maxBlue, ratio);
return new Color(red, green, blue);
} }
if (value < 0) { if (value < 0) {
double ratio = -value; double ratio = -value;
return new Color((int) (minColor.getRed() * ratio), (int) (minColor.getGreen() * ratio), int red = getColorForRatio(neutralRed, minRed, ratio);
(int) (minColor.getBlue() * ratio)); int green = getColorForRatio(neutralGreen, minGreen, ratio);
int blue = getColorForRatio(neutralBlue, minBlue, ratio);
return new Color(red, green, blue);
} }
return Color.WHITE; return neutralColor;
}
private int getColorForRatio(int neutralRed, int maxRed, double ratio) {
int red = (int) Math.round(neutralRed + (maxRed - neutralRed) * ratio);
red = Math.max(0, red);
red = Math.min(255, red);
return red;
} }
/** /**
...@@ -104,4 +130,8 @@ public class ColorExtractor { ...@@ -104,4 +130,8 @@ public class ColorExtractor {
public Color getSimpleColor() { public Color getSimpleColor() {
return simpleColor; return simpleColor;
} }
public Color getNeutralColor() {
return neutralColor;
}
} }
...@@ -13,6 +13,7 @@ import lcsb.mapviewer.commands.properties.AllPropertyCommandTests; ...@@ -13,6 +13,7 @@ import lcsb.mapviewer.commands.properties.AllPropertyCommandTests;
AllLayoutTests.class, AllLayoutTests.class,
AllPropertyCommandTests.class, AllPropertyCommandTests.class,
ClearColorModelCommandTest.class, ClearColorModelCommandTest.class,
ColorExtractorTest.class,
ColorModelCommandTest.class, ColorModelCommandTest.class,
CopyCommandTest.class, CopyCommandTest.class,
CreateHierarchyCommandTest.class, CreateHierarchyCommandTest.class,
......
package lcsb.mapviewer.commands;
import static org.junit.Assert.assertEquals;
import java.awt.Color;
import org.junit.Test;
public class ColorExtractorTest {
ColorExtractor extractor = new ColorExtractor(Color.GREEN, Color.BLUE, Color.RED, Color.YELLOW);
@Test
public void testZeroColor() {
assertEquals(Color.YELLOW, extractor.getColorForValue(0.0001));
assertEquals(Color.YELLOW, extractor.getColorForValue(0.0));
}
@Test
public void testMaxColor() {
assertEquals(Color.BLUE, extractor.getColorForValue(1.0));
assertEquals(Color.BLUE, extractor.getColorForValue(0.99999));
}
@Test
public void testMinColor() {
assertEquals(Color.GREEN, extractor.getColorForValue(-1.0));
assertEquals(Color.GREEN, extractor.getColorForValue(-0.99999));
}
@Test
public void testColorForNotNormalizedValue() {
assertEquals(Color.GREEN, extractor.getColorForValue(-10.0));
assertEquals(Color.BLUE, extractor.getColorForValue(10.0));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment