android VectorDrawable 转png图片

Android上使用svg图片可以利用VectorDrawable,不仅体积小而且是矢量图,目前已经成为了开发app的不二之选。下面是一个VectorDrawable例子:

<?xml version="1.0" encoding="utf-8"?>  
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="26dp" android:width="26dp" android:viewportWidth="26" android:viewportHeight="26">  
    <path android:fillColor="#ee4f4f" android:pathData="M15.746,21.714C15.036,22.541 14.017,23.015 12.95,23.015C11.858,23.015 10.856,22.461 9.86,21.292L5.694,16.932L20.307,16.932L15.746,21.714ZM22.498,10.817C22.498,5.404 18.237,1 12.998,1C7.761,1 3.5,5.404 3.5,10.817L3.5,16.205C3.5,16.266 3.52,16.32 3.534,16.377C3.519,16.58 3.578,16.786 3.727,16.943L8.83,22.283C10.065,23.733 11.451,24.469 12.95,24.469C14.419,24.469 15.822,23.817 16.773,22.708L22.213,17.005C22.336,16.877 22.395,16.711 22.406,16.544C22.459,16.441 22.498,16.329 22.498,16.205L22.498,10.817Z" android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>  

我们这篇文章主角是小程序,在小程序上怎么使用svg呢?只能通过svg转成base64,然后显示出来。还有另一种就是我们这篇要介绍的,直接把svg转png图片。

VectorDrawable是Android专用的格式,严格意义上说并不是svg,不过总体上是一致的,可以通过替换标签来转换。

#VectorDrawable2Svg.py

"""
VectorDrawable2Svg  
This script convert your VectorDrawable to a Svg  
Author: Alessandro Lucchet

Usage: drop one or more vector drawable onto this script to convert them to svg format  
"""

from xml.dom.minidom import *  
import sys

# extracts all paths inside vdContainer and add them into svgContainer
def convertPaths(vdContainer,svgContainer,svgXml):  
    vdPaths = vdContainer.getElementsByTagName('path')
    for vdPath in vdPaths:
        # only iterate in the first level
        if vdPath.parentNode == vdContainer:
            svgPath = svgXml.createElement('path')
            svgPath.attributes['d'] = vdPath.attributes['android:pathData'].value
            if vdPath.hasAttribute('android:fillColor'):
                svgPath.attributes['fill'] = vdPath.attributes['android:fillColor'].value
            else:
                svgPath.attributes['fill'] = 'none'
            if vdPath.hasAttribute('android:strokeLineJoin'):
                svgPath.attributes['stroke-linejoin'] = vdPath.attributes['android:strokeLineJoin'].value
            if vdPath.hasAttribute('android:strokeLineCap'):
                svgPath.attributes['stroke-linecap'] = vdPath.attributes['android:strokeLineCap'].value
            if vdPath.hasAttribute('android:strokeMiterLimit'):
                svgPath.attributes['stroke-miterlimit'] = vdPath.attributes['android:strokeMiterLimit'].value
            if vdPath.hasAttribute('android:strokeWidth'):
                svgPath.attributes['stroke-width'] = vdPath.attributes['android:strokeWidth'].value
            if vdPath.hasAttribute('android:strokeColor'):
                svgPath.attributes['stroke'] = vdPath.attributes['android:strokeColor'].value
            svgContainer.appendChild(svgPath);

# define the function which converts a vector drawable to a svg
def convertVd(vdFilePath):

    # create svg xml
    svgXml = Document()
    svgNode = svgXml.createElement('svg')
    svgXml.appendChild(svgNode);

    # open vector drawable
    vdXml = parse(vdFilePath)
    vdNode = vdXml.getElementsByTagName('vector')[0]

    # setup basic svg info
    svgNode.attributes['xmlns'] = 'http://www.w3.org/2000/svg'
    svgNode.attributes['width'] = vdNode.attributes['android:viewportWidth'].value
    svgNode.attributes['height'] = vdNode.attributes['android:viewportHeight'].value
    svgNode.attributes['viewBox'] = '0 0 {} {}'.format(vdNode.attributes['android:viewportWidth'].value, vdNode.attributes['android:viewportHeight'].value)

    # iterate through all groups
    vdGroups = vdXml.getElementsByTagName('group')
    for vdGroup in vdGroups:

        # create the group
        svgGroup = svgXml.createElement('g')

        # setup attributes of the group
        if vdGroup.hasAttribute('android:translateX'):
            svgGroup.attributes['transform'] = 'translate({},{})'.format(vdGroup.attributes['android:translateX'].value,vdGroup.attributes['android:translateY'].value)

        # iterate through all paths inside the group
        convertPaths(vdGroup,svgGroup,svgXml)

        # append the group to the svg node
        svgNode.appendChild(svgGroup);

    # iterate through all svg-level paths
    convertPaths(vdNode,svgNode,svgXml)

    # write xml to file
    svgXml.writexml(open(vdFilePath + '.svg', 'w'),indent="",addindent="  ",newl='\n')

# script begin
if len(sys.argv)>1:  
    iterArgs = iter(sys.argv)
    next(iterArgs) #skip the first entry (it's the name of the script)
    for arg in iterArgs:
        convertVd(arg)
else:  
    print("You have to pass me something")
    sys.exit()

这是从stackOverFlow下载的脚本,原作者已经找不到,在此致谢。使用方式的话在代码里有说明。python VectorDrawable2Svg.py <需要转换的文件> 下面是转换后的svg代码:

<?xml version="1.0" ?>  
<svg height="26" viewBox="0 0 26 26" width="26" xmlns="http://www.w3.org/2000/svg">  
  <path d="M15.746,21.714C15.036,22.541 14.017,23.015 12.95,23.015C11.858,23.015 10.856,22.461 9.86,21.292L5.694,16.932L20.307,16.932L15.746,21.714ZM22.498,10.817C22.498,5.404 18.237,1 12.998,1C7.761,1 3.5,5.404 3.5,10.817L3.5,16.205C3.5,16.266 3.52,16.32 3.534,16.377C3.519,16.58 3.578,16.786 3.727,16.943L8.83,22.283C10.065,23.733 11.451,24.469 12.95,24.469C14.419,24.469 15.822,23.817 16.773,22.708L22.213,17.005C22.336,16.877 22.395,16.711 22.406,16.544C22.459,16.441 22.498,16.329 22.498,16.205L22.498,10.817Z" fill="#ee4f4f" stroke="#00000000" stroke-width="1"/>
</svg>

通过这个脚本,我们就可以把VectorDrawable转换成SVG了,在mac上也可以预览了。怎么转成图片呢?我们借助一些第三方工具。网上找了很多工具,觉得最好用的还是Boxy SVG

软件的用法就不介绍了,都是界面化操作,基本没啥难度。到此就把VectorDrawable转成png了