我正努力通过css(svg作为背景css)来改变svg对象的颜色。
我有这个
span {
display:block;
width: 12px;
background: url('data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ><polygon points="6,4.5 0,0 0,1.208 6,5.708 12,1.208 12,0"/></svg>');
height: 20px;
}
这样可以,但元素的颜色总是黑色。我想将其颜色更改为自定义颜色(例如蓝色)。
通过添加style="fill:#2C30FF"
,该元素只会消失并且不显示任何内容,但如果svg元素包含在html(不是css背景)中,则此工作正常
请参阅小提琴以获取示例。应该显示3个元素,但第二个元素没有显示,因为我添加了style="fill:#2C30FF"
为什么它不起作用?非常感谢一些提示。
答案 0 :(得分:1)
#是网址中的保留字符,表示start of a fragment identifier。
您需要将#编码为%23
background: url('data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ><polygon points="6,4.5 0,0 0,1.208 6,5.708 12,1.208 12,0" style="fill:%232C30FF;"/></svg>');
答案 1 :(得分:-1)
我刚刚实现了一个java解决方案,我可以加载SVG文件并动态更改填充颜色。
package com.svg.poc;
import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.anim.dom.SVGDOMImplementation;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.BridgeException;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.util.ParsedURL;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
public final class SvgImage {
private GraphicsNode rootSvgNode;
private SVGDocument svgDocument;
public SvgImage(String imagePath) throws IOException {
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
svgDocument = (SVGDocument) factory.createDocument(imagePath);
rootSvgNode = getRootNode(svgDocument);
}
public SvgImage(SVGDocument document) {
svgDocument = document;
rootSvgNode = getRootNode(svgDocument);
}
private static GraphicsNode getRootNode(SVGDocument document) {
UserAgentAdapter userAgentAdapter = new UserAgentAdapter();
BridgeContext bridgeContext = new BridgeContext(userAgentAdapter);
GVTBuilder builder = new GVTBuilder();
return builder.build(bridgeContext, document);
}
public BufferedImage getImage(Integer heightOverride, Integer widthOverride) {
int height = (heightOverride == null || heightOverride.intValue() == 0) ? fetchExistingImageHeightValue() : heightOverride;
int width = (widthOverride == null || widthOverride.intValue() == 0) ? fetchExistingImageWidthValue() : widthOverride;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = GraphicsUtil.createGraphics(bufferedImage);
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
SVGDocument cloneDocument = (SVGDocument) DOMUtilities.deepCloneDocument(svgDocument, impl);
SVGSVGElement root = cloneDocument.getRootElement();
// @@TODO - Currently hardcoded the inbound new color for testing, will use the ReportConfiguration Colors soon.
//String hardCodedHexColor = "#ff00ff"; // pink
String hardCodedHexColor = "#008000"; // green
updateTagFillColor(root.getElementsByTagName("rect"), hardCodedHexColor);
updateTagFillColor(root.getElementsByTagName("path"), hardCodedHexColor);
UserAgentAdapter userAgentAdapter = new UserAgentAdapter();
BridgeContext ctx = new BridgeContext(userAgentAdapter);
ctx.setDynamic(true);
GVTBuilder builder = new GVTBuilder();
GraphicsNode gvtRoot = builder.build(ctx, cloneDocument);
AffineTransform px = new AffineTransform();
String ref = new ParsedURL(svgDocument.getBaseURI()).getRef();
try {
px = ViewBox.getViewTransform(ref, root, width, height, ctx);
} catch (BridgeException ex) {
ex.printStackTrace();
}
g2d.transform(px);
gvtRoot.paint(g2d);
// Cleanup and return image
g2d.dispose();
return bufferedImage;
}
private void updateTagFillColor(NodeList nodeList, String newFillColor) {
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
NamedNodeMap namedNodeMap = node.getAttributes();
for (int j = 0; j < namedNodeMap.getLength(); j++) {
Node namedNode = namedNodeMap.item(j);
if (namedNode.getNodeName().equalsIgnoreCase("fill")) {
StringBuilder beforeBuilder = new StringBuilder("\nBefore update: ")
.append("node name=" + namedNode.getNodeName())
.append(", node value=" + namedNode.getNodeValue());
System.out.println(beforeBuilder.toString());
namedNode.setNodeValue(newFillColor); // Change the color of the fill attribute.
StringBuilder afterBuilder = new StringBuilder("After update: ")
.append("node name=" + namedNode.getNodeName())
.append(", node value=" + namedNode.getNodeValue());
System.out.println(afterBuilder.toString());
}
}
}
}
private int fetchExistingImageWidthValue() {
return new Double(rootSvgNode.getBounds().getWidth()).intValue();
}
private int fetchExistingImageHeightValue() {
return new Double(rootSvgNode.getBounds().getHeight()).intValue();
}
}
实现:(调用此类 - 接口)
package com.svg.poc;
import java.awt.image.BufferedImage;
public interface SvgIconImageRenderer {
BufferedImage getSvgImage(String svgImageFilePath);
BufferedImage getSvgImage(String svgImageFilePath, Integer heightOverride, Integer widthOverride);
}
实现:(调用此类 - 实现类)
package com.svg.poc;
import org.springframework.stereotype.Component;
import java.awt.image.BufferedImage;
@Component
public class SvgIconImageRendererImpl implements SvgIconImageRenderer {
public BufferedImage getSvgImage(String svgImageFilePath) {
return getSvgImage(svgImageFilePath, null, null);
}
public BufferedImage getSvgImage(String svgImageFilePath, Integer heightOverride, Integer widthOverride) {
try {
SvgImage svgImage = new SvgImage(getClass().getResource(svgImageFilePath).toURI().toString());
return svgImage.getImage(heightOverride, widthOverride);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
}
package com.svg.poc;
import org.apache.batik.swing.JSVGCanvas;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
public class SVGImageLoaderTest {
private SvgIconImageRenderer svgIconImageRenderer = new SvgIconImageRendererImpl();
private static final String ICON_HOUSES_SVG_URL_PATH = "/icon-houses.svg";
public static void main(String[] args) {
JFrame f = new JFrame("Svg Image test");
SVGImageLoaderTest app = new SVGImageLoaderTest(f);
f.getContentPane().add(app.createComponents());
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setSize(400, 400);
f.setVisible(true);
}
JFrame frame;
JSVGCanvas svgCanvas = new JSVGCanvas();
public SVGImageLoaderTest(JFrame f) {
frame = f;
}
public JComponent createComponents() {
BufferedImage bufferedSvgImage = svgIconImageRenderer.getSvgImage(ICON_HOUSES_SVG_URL_PATH);
JLabel label = new JLabel(new ImageIcon(bufferedSvgImage));
final JPanel panel = new JPanel(new BorderLayout());
JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
p.add(label);
panel.add(p, BorderLayout.NORTH);
panel.add(svgCanvas, BorderLayout.CENTER);
return panel;
}
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="300px" height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
<g>
<rect x="5" y="5" width="200" fill="#ff0000" height="30" rx="15" ry="15" stroke="gray" />
<rect x="5" y="45" width="400" fill="#ff0000" height="30" rx="15" ry="15" stroke="gray" />
<path display="inline" fill="#8D8379" d="M243.754,124.987c-31.017,0-56.246,25.249-56.246,56.257
c0,28.494,45.661,106.85,50.86,115.676c1.128,1.911,3.173,3.08,5.386,3.08c2.212,0,4.27-1.169,5.395-3.08
c5.208-8.826,50.862-87.182,50.862-115.676C300.011,150.236,274.771,124.987,243.754,124.987 M243.754,212.498
c-17.241,0-31.255-14.015-31.255-31.254c0-17.229,14.014-31.256,31.255-31.256c17.24,0,31.254,14.026,31.254,31.256
C275.008,198.483,260.995,212.498,243.754,212.498"/>
</g>
<polygon display="inline" fill="#8D8379" points="149.046,153.722 149.013,153.722 149.08,153.722 "/>
</svg>
<dependencies>
<!--svg image dependencies-->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-transcoder</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-swing</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>xmlgraphics-commons</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
</dependencies>