- qinshulei / ConvertAndroidVectorDrawable2png.md
- This comment has been minimized.
- xxtesaxx commented Apr 30, 2017
- This comment has been minimized.
- ozmium commented Aug 4, 2017 •
- This comment has been minimized.
- martinellimarco commented Oct 12, 2017
- Легко переходим на векторный формат картинок вместо нарезки под разные плотности экранов в Android 4.0+. Часть 2 из 2
- SVG to VectorDrawable Converter
- Установка зависимостей
- Если у Вас Windows
- Microsoft .NET Framework
- Inkscape
- Если у Вас OS X
- Inkscape
qinshulei / ConvertAndroidVectorDrawable2png.md
- Convert Android VectorDrawable to SVG:
./*.xml为目标Android VectorDrawable的xml文件列表 然后程序会在对应目录生成同名的svg
This file contains 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 characters
/* |
* Copyright (C) 2015. Jared Rummler |
* |
* 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( » |
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; |
> |
> |
> |
This comment has been minimized.
Copy link Quote reply
xxtesaxx commented Apr 30, 2017
Awesome! This Android VectorDrawable to SVG Converter is exactly what I needed to convert Android xml to svg or to convert my Android xml to png. Thank you very much.
This comment has been minimized.
Copy link Quote reply
ozmium commented Aug 4, 2017 •
On line 78, you need to add: svg.setAttribute(«xmlns», «http://www.w3.org/2000/svg»);
On line 169 to 171, you need this:
This comment has been minimized.
Copy link Quote reply
martinellimarco commented Oct 12, 2017
Add a default Locale int String.format, like this:
svg.setAttribute(«viewBox», String.format(Locale.ROOT, «0 0 %.1f %.1f», drawable.width, drawable.height));
otherwhise on certain Locale (for example italian) numbers will be formatted with , instead of . as decimal separator.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник
Легко переходим на векторный формат картинок вместо нарезки под разные плотности экранов в Android 4.0+. Часть 2 из 2
В предыдущей части мы обсудили библиотеку BetterVectorDrawable, реализующую VectorDrawable для Android 4.0+.
В этой части речь пойдет о преобразовании изображений из SVG в vector drawable XML.
Когда Андроид читает XML-ресурсы, он игнорирует атрибуты, которые не поддерживаются текущим устройством. Это означает, что неподдерживаемые атрибуты в vector drawable XML придется продублировать в пространстве имен schemas.android.com/apk/res-auto , чтобы у BetterVectorDrawable была возможность их прочитать. Например:
При этом нужно дублировать только неподдерживаемые атрибуты (список можно посмотреть здесь; см. атрибуты без префикса android: ).
К счастью, все это для нас проделывает конвертер и нам не нужно даже задумываться об этом.
SVG to VectorDrawable Converter
Этот конвертер позволяет создавать vector drawable ресурсы как для Android 5.0+, так и для библиотеки BetterVectorDrawable. Это контролируется с помощью аргумента командной строки.
Конвертер является кроссплатформенным консольным приложением: его можно запустить на Windows или OS X. Для его работы требуется установить зависимости, об этом речь пойдет позже. Сам конвертер распространяется в виде архива с исполняемым файлом, который можно скачать здесь.
Архив нужно распаковать и, открыв консоль на Windows (терминал на OS X), сменить текущую директорию на директорию с конвертером.
Команда, запускающая конвертацию, выглядит так:
Опциональные параметры указаны в квадратных скобках (хотя используются без скобок):
- mono следует указать, если Вы запускаете конвертер на OS X
- —lib BetterVectorDrawable следует указать, если Вы хотите, чтобы в выходных XML были продублированы неподдерживаемые атрибуты, т.е. сконвертировать SVG в vector drawable XML для библиотеки BetterVectorDrawable, иначе конвертер создаст vector drawable ресурсы для Android 5.0+.
Остальные параметры, думаю, понятны и так; аргумент —help выводит их описания.
Установка зависимостей
Если у Вас Windows
Microsoft .NET Framework
Если у Вас Windows 8 или выше, то этот пункт можно пропустить.
В системе должен быть установлен .NET Framework 4.5+. Проверить версию установленного .NET Framework можно согласно этой инструкции. Скачать .NET Framework 4.5 можно здесь.
Inkscape
Inkscape – это бесплатный редактор векторной графики с открытым кодом. Установка под Windows не отличается от обычной установки программы. Скачать можно здесь.
Если у Вас OS X
Понадобиться OS X 10.7 или лучше.
Скачать Mono можно здесь. Установка у меня прошла без затруднений.
Inkscape
Inkscape – это бесплатный редактор векторной графики с открытым кодом. Для установки под OS X сначала потребуется установить XQuartz, после чего нужно перезапустить компьютер или выйти и снова войти в систему.
Скачать Inkscape можно здесь. Убедитесь, что после установки Inkscape свободно запускается. Мне потребовалось разблокировать его в System Preferences… → Security & Privacy → General. Нужно нажать Click the lock to make changes и разблокировать запуск Inkscape.
Если у Вас возникли затруднения, можно написать мне. О проблемах с конвертером лучше сообщать разработчикам в GitHub, добавив ссылку на проблемный SVG-файл.
Источник