Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 12964)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 12966)
@@ -10,4 +10,5 @@
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 
 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
@@ -17,4 +18,5 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
@@ -69,4 +71,6 @@
     private final Map<String, String> preferenceCache = new HashMap<>();
 
+    private static volatile Color backgroundColorCache;
+
     /**
      * Constructs a new {@code ElemStyles}.
@@ -75,4 +79,16 @@
         styleSources = new ArrayList<>();
         Config.getPref().addPreferenceChangeListener(this);
+        MapPaintStyles.addMapPaintSylesUpdateListener(new MapPaintStyles.MapPaintSylesUpdateListener() {
+            //TODO: Listen to wireframe map mode changes.
+            @Override
+            public void mapPaintStylesUpdated() {
+                backgroundColorCache = null;
+            }
+
+            @Override
+            public void mapPaintStyleEntryUpdated(int idx) {
+                mapPaintStylesUpdated();
+            }
+        });
     }
 
@@ -94,4 +110,19 @@
     public List<StyleSource> getStyleSources() {
         return Collections.<StyleSource>unmodifiableList(styleSources);
+    }
+
+    public Color getBackgroundColor() {
+        if (backgroundColorCache != null)
+            return backgroundColorCache;
+        for (StyleSource s : styleSources) {
+            if (!s.active) {
+                continue;
+            }
+            Color backgroundColorOverride = s.getBackgroundColorOverride();
+            if (backgroundColorOverride != null) {
+                backgroundColorCache = backgroundColorOverride;
+            }
+        }
+        return Optional.ofNullable(backgroundColorCache).orElseGet(PaintColors.BACKGROUND::get);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/RenderingCLI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/RenderingCLI.java	(revision 12964)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/RenderingCLI.java	(revision 12966)
@@ -5,4 +5,6 @@
 
 import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -14,4 +16,6 @@
 import java.util.function.Supplier;
 import java.util.logging.Level;
+
+import javax.imageio.ImageIO;
 
 import org.openstreetmap.gui.jmapviewer.OsmMercator;
@@ -155,7 +159,7 @@
             RenderingArea area = determineRenderingArea(ds);
             RenderingHelper rh = new RenderingHelper(ds, area.bounds, area.scale, argStyles);
-            rh.setOutputFile(argOutput);
             checkPreconditions(rh);
-            rh.render();
+            BufferedImage image = rh.render();
+            writeImageToFile(image);
         } catch (FileNotFoundException e) {
             if (Logging.isDebugEnabled()) {
@@ -562,3 +566,8 @@
         }
     }
+
+    private void writeImageToFile(BufferedImage image) throws IOException {
+        String output = Optional.ofNullable(argOutput).orElse("out.png");
+        ImageIO.write(image, "png", new File(output));
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/RenderingHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/RenderingHelper.java	(revision 12964)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/RenderingHelper.java	(revision 12966)
@@ -4,9 +4,10 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Graphics2D;
 import java.awt.Point;
+import java.awt.RenderingHints;
 import java.awt.image.BufferedImage;
-import java.io.File;
 import java.io.IOException;
 import java.util.Collection;
@@ -15,11 +16,8 @@
 import java.util.Optional;
 
-import javax.imageio.ImageIO;
-
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer;
 import org.openstreetmap.josm.data.projection.Projection;
@@ -41,5 +39,6 @@
     private final double scale;
     private final Collection<StyleData> styles;
-    private String outputFile;
+    private Color backgroundColor;
+    private boolean fillBackground = true;
 
     /**
@@ -73,11 +72,23 @@
 
     /**
-     * Set the output file for rendering.
+     * Set the background color to use for rendering.
      *
-     * Default is {@code out.png}.
-     * @param outputFile the output file for rendering
+     * @param backgroundColor the background color to use, {@code} means
+     * to determine the background color automatically from the style
+     * @see #setFillBackground(boolean)
+     * @since 12966
      */
-    public void setOutputFile(String outputFile) {
-        this.outputFile = outputFile;
+    public void setBackgroundColor(Color backgroundColor) {
+        this.backgroundColor = backgroundColor;
+    }
+
+    /**
+     * Decide if background should be filled or left transparent.
+     * @param fillBackground true, if background should be filled
+     * @see #setBackgroundColor(java.awt.Color)
+     * @since 12966
+     */
+    public void setFillBackground(boolean fillBackground) {
+        this.fillBackground = fillBackground;
     }
 
@@ -93,8 +104,9 @@
      * Invoke the renderer.
      *
+     * @return the rendered image
      * @throws IOException in case of an IOException
      * @throws IllegalDataException when illegal data is encountered (style has errors, etc.)
      */
-    public void render() throws IOException, IllegalDataException {
+    public BufferedImage render() throws IOException, IllegalDataException {
         // load the styles
         ElemStyles elemStyles = new ElemStyles();
@@ -152,13 +164,24 @@
         BufferedImage image = new BufferedImage(imgDimPx.width, imgDimPx.height, BufferedImage.TYPE_INT_ARGB);
         Graphics2D g = image.createGraphics();
-        g.setColor(PaintColors.getBackgroundColor());
-        g.fillRect(0, 0, imgDimPx.width, imgDimPx.height);
+
+        // Force all render hints to be defaults - do not use platform values
+        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
+        g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+        g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
+        g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+        g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
+        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+        if (fillBackground) {
+            g.setColor(Optional.ofNullable(backgroundColor).orElse(elemStyles.getBackgroundColor()));
+            g.fillRect(0, 0, imgDimPx.width, imgDimPx.height);
+        }
         StyledMapRenderer smr = new StyledMapRenderer(g, nc, false);
         smr.setStyles(elemStyles);
         smr.render(ds, false, bounds);
-
-        // write to file
-        String output = Optional.ofNullable(outputFile).orElse("out.png");
-        ImageIO.write(image, "png", new File(output));
+        return image;
     }
 
