Forked from qinshulei/ConvertAndroidVectorDrawable2png.md
Created
February 1, 2021 22:27
-
-
Save Bicet/33ff29db1bf7600ad35e15c22d5be8c5 to your computer and use it in GitHub Desktop.
Revisions
-
qinshulei revised this gist
Nov 12, 2015 . 1 changed file with 216 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,216 @@ /* * Copyright (C) 2015. Jared Rummler <[email protected]> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; public class Vector2Svg { public static void main(String[] args) { if (args == null || args.length == 0 || args[0].equals("--help")) { printUsage(); return; } for (String path : args) { Vector2Svg converter = new Vector2Svg(new File(path)); if (!converter.createSvg()) { System.out.println("Error creating SVG from " + path); } } } private static void printUsage() { File jarFile = new File(Vector2Svg.class.getProtectionDomain().getCodeSource().getLocation().getPath()); System.out.println("Convert Android VectorDrawable XML resource file to SVG"); System.out.println(); System.out.println(String.format("Usage: java -jar %s [FILE]...", jarFile.getName())); } private final File source; private final File destination; public Vector2Svg(File source) { this(source, new File(source.getParent(), source.getName().replaceFirst("[.][^.]+$", ".svg"))); } public Vector2Svg(File source, File destination) { this.source = source; this.destination = destination; } public boolean createSvg() { try { AndroidVectorDrawable drawable = getDrawable(); Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element svg = doc.createElement("svg"); svg.setAttribute("viewBox", String.format("0 0 %.1f %.1f", drawable.width, drawable.height)); for (Group group : drawable.groups) { Element g = doc.createElement("g"); for (VectorPath path : group.paths) { Element child = doc.createElement("path"); if (path.fillColor != null) { child.setAttribute("fill", path.fillColor); } child.setAttribute("d", path.pathData); g.appendChild(child); } svg.appendChild(g); } for (VectorPath path : drawable.paths) { Element child = doc.createElement("path"); if (path.fillColor != null) { child.setAttribute("fill", path.fillColor); } child.setAttribute("d", path.pathData); svg.appendChild(child); } doc.appendChild(svg); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult(destination); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); transformer.transform(source, result); return true; } catch (Exception e) { return false; } } private AndroidVectorDrawable getDrawable() throws ParserConfigurationException, IOException, SAXException { Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source); xml.getDocumentElement().normalize(); Node vector = xml.getElementsByTagName("vector").item(0); NamedNodeMap attributes = vector.getAttributes(); NodeList children = vector.getChildNodes(); double width = 0; double height = 0; for (int i = 0; i < attributes.getLength(); i++) { if (attributes.item(i).getNodeName().equals("android:viewportHeight")) { height = Double.parseDouble(attributes.item(i).getNodeValue()); } else if (attributes.item(i).getNodeName().equals("android:viewportWidth")) { width = Double.parseDouble(attributes.item(i).getNodeValue()); } } List<VectorPath> paths = new ArrayList<>(); List<Group> groups = new ArrayList<>(); for (int i = 0; i < children.getLength(); i++) { Node item = children.item(i); if (item.getNodeName().equals("group")) { List<VectorPath> groupPaths = new ArrayList<>(); for (int j = 0; j < item.getChildNodes().getLength(); j++) { VectorPath path = getVectorPathFromNode(item.getChildNodes().item(j)); if (path != null) { groupPaths.add(path); } } if (!groupPaths.isEmpty()) { groups.add(new Group(groupPaths)); } } else { VectorPath path = getVectorPathFromNode(item); if (path != null) { paths.add(path); } } } return new AndroidVectorDrawable(paths, groups, width, height); } private VectorPath getVectorPathFromNode(Node item) { if (item.getNodeName().equals("path")) { String pathData = null; String fillColor = null; for (int j = 0; j < item.getAttributes().getLength(); j++) { Node node = item.getAttributes().item(j); String name = node.getNodeName(); String value = node.getNodeValue(); if (name.equals("android:pathData")) { pathData = value; } else if (name.equals("android:fillColor") && value.startsWith("#")) { fillColor = value; } } if (pathData != null) { return new VectorPath(pathData, fillColor); } } return null; } private class VectorPath { private String pathData; private String fillColor; private VectorPath(String pathData, String fillColor) { this.pathData = pathData; this.fillColor = fillColor; } } private class Group { private final List<VectorPath> paths; public Group(List<VectorPath> paths) { this.paths = paths; } } private class AndroidVectorDrawable { private final List<VectorPath> paths; private final List<Group> groups; private final double height; private final double width; private AndroidVectorDrawable(List<VectorPath> paths, List<Group> groups, double width, double height) { this.paths = paths; this.groups = groups; this.height = height; this.width = width; } } } -
qinshulei created this gist
Nov 12, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,29 @@ 转换方法: 1. Convert Android VectorDrawable to SVG: 使用附件中的java程序。命令如下: ``` cp Vector2Svg.java path/to/xml_dir javac Vector2Svg.java java Vector2Svg ./*.xml mkdir svg_dir mv *.svg svg_dir ``` ./*.xml为目标Android VectorDrawable的xml文件列表 然后程序会在对应目录生成同名的svg 2. Convert SVG to PNG: 最简单的方法是直接使用Ubuntu的图片浏览器打开,然后另存为png 批量转换: ``` sudo apt-get install librsvg2-bin cd svg_dir for i in *; do rsvg-convert $i -o `echo $i | sed -e 's/svg$/png/'`; done ``` 安装rsvg库,使用rsvg 转换svg到png. 附件中svg.tgz,是昨天图片的png结果。