美文网首页
svg在android上的应用

svg在android上的应用

作者: zhnd | 来源:发表于2017-10-09 20:35 被阅读0次

    背景

    SVG:可缩放矢量图形(Scalable Vector Graphics),基于可扩展标记语言(XML),是W3C("World Wide Web ConSortium",国际互联网标准组织)在2000年8月制定的一种新的二维矢量图形格式,于2003年1月14日成为W3C推荐标准。

    矢量图特点:
    优点
    (1)文件小;
    (2)图像元素对象可编辑;
    (3)图像放大或缩小不影响图像的分辨率;
    (4)图像的分辨率不依赖于输出设备;
    (5)线条非常顺滑并且是同样粗细的;
    (6)颜色的边缘是非常顺滑的。
    缺点
    (1)重画图像困难;
    (2)真实照片逼真度低,要画出自然度高的图像需要很多的技巧;
    (3)无法产生色彩艳丽、复杂多变的图像;
    (4)矢量图仿图绘制做卡通的相似度97%以上,3%是清晰美化的。

    SVG优势:
    SVG 可被非常多的工具读取和修改(比如记事本)
    SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强
    SVG 是可伸缩的
    SVG 图像可在任何的分辨率下被高质量地打印
    SVG 可在图像质量不下降的情况下被放大
    SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
    SVG 可以与 Java 技术一起运行
    SVG 是开放的标准
    SVG 文件是纯粹的 XML

    矢量图很适合用于记录诸如符号、图标等简单的图形。而位图则适合于没有明显规律的、颜色丰富细腻的图片。

    Android微信上的SVG

    SVG教程jpg,png图片在线转svgsvgeditor

    应用

    1、android svg

    在Android 5.X之后,Android中添加了对SVG的path标签的支持。

    示例

    svg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="100dp"
        android:height="100dp"
        android:viewportHeight="100"
        android:viewportWidth="100">
    
        <group>
            <path
                android:name="path3"
                android:pathData="
                M 0,0
                L 100,0
                  100,100
                "
                android:strokeColor="#222222"
                android:strokeLineCap="round"
                android:strokeWidth="1" />
        </group>
    
    </vector>
    

    anim_path3.xml

    <?xml version="1.0" encoding="utf-8"?>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:propertyName="pathData"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:valueFrom="
                M 0,0
                L 100,0
                  100,100
                "
        android:valueTo="
                M 0,0
                L 0,100
                  100,100
                "
        android:valueType="pathType" />
    

    anim_svg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/svg">
    
        <target
            android:name="path3"
            android:animation="@animator/anim_path3" />
    
    </animated-vector>
    
    path标签
    M = moveto(M X,Y):将画笔移动到指定的坐标位置,但未发生绘制
    
    L = lineto(L X,Y):画直线到指定的坐标位置
    
    H = horizontal lineto(H X):画水平线到指定的X轴坐标
    
    V = vertical lineto(V Y):画垂直线到指定的Y轴坐标
    
    C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝塞曲线
    
    S = smooth curveto(S X2,Y2,ENDX,ENDY):三次贝塞曲线
    
    Q = quadratic Belzier curveto(Q X,Y,ENDX,ENDY):二次贝塞曲线
    
    T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射前面路径后的终点
    
    A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线
    
    Z = closepath():关闭路径
    

    2、glide

    glide-svgGlide从v3迁移到v4
    glide库支持加载本地或网络的svg图片。

    示例
    RequestBuilder<PictureDrawable> requestBuilder = GlideApp.with(this)
                    .as(PictureDrawable.class)
                    .transition(withCrossFade())
                    .listener(new SvgSoftwareLayerSetter());
    requestBuilder.load("http://www.webhek.com/wordpress/wp-content/uploads/2014/05/kiwi.svg").into(viewImage1);
    requestBuilder.load(R.raw.spiral).into(viewImage2);
    

    使用下面这种方式同样可以加载svg图片,不过显示没有上面那种方式清晰。

    Glide.with(this).load("http://www.webhek.com/wordpress/wp-content/uploads/2014/05/kiwi.svg").into(viewImage3);
    Glide.with(this).load(R.raw.spiral).into(viewImage4);
    

    对比如下图:


    IMG_20171009_140905.jpg

    通过查看代码,可以看到glide用到了androidsvg库。

    import com.caverock.androidsvg.SVG;
    
    20171009114721.png
    androidsvg:GitHub官网
    SVGParser.class
    private static final String TAG_SVG = "svg";
    private static final String TAG_A = "a";
    private static final String TAG_CIRCLE = "circle";
    private static final String TAG_CLIPPATH = "clipPath";
    private static final String TAG_DEFS = "defs";
    private static final String TAG_DESC = "desc";
    private static final String TAG_ELLIPSE = "ellipse";
    private static final String TAG_G = "g";
    private static final String TAG_IMAGE = "image";
    private static final String TAG_LINE = "line";
    private static final String TAG_LINEARGRADIENT = "linearGradient";
    private static final String TAG_MARKER = "marker";
    private static final String TAG_MASK = "mask";
    private static final String TAG_PATH = "path";
    private static final String TAG_PATTERN = "pattern";
    private static final String TAG_POLYGON = "polygon";
    private static final String TAG_POLYLINE = "polyline";
    private static final String TAG_RADIALGRADIENT = "radialGradient";
    private static final String TAG_RECT = "rect";
    private static final String TAG_SOLIDCOLOR = "solidColor";
    private static final String TAG_STOP = "stop";
    private static final String TAG_STYLE = "style";
    private static final String TAG_SWITCH = "switch";
    private static final String TAG_SYMBOL = "symbol";
    private static final String TAG_TEXT = "text";
    private static final String TAG_TEXTPATH = "textPath";
    private static final String TAG_TITLE = "title";
    private static final String TAG_TREF = "tref";
    private static final String TAG_TSPAN = "tspan";
    private static final String TAG_USE = "use";
    private static final String TAG_VIEW = "view";
    

    这个库支持的svg标签。

    3、android-pathview

    android-pathview
    通过android-pathview库可以实现svg动画效果。

    示例
    viewPath.setSvgResource(R.raw.monitor);
    viewPath.useNaturalColors();
    viewPath.setFillAfter(true);
    viewPath.getPathAnimator()
            .delay(100)
            .duration(1000)
            .interpolator(new AccelerateDecelerateInterpolator())
            .start();
    

    PathView.java

    /**
     * Set the svg resource id.
     *
     * @param svgResource - The resource id of the raw svg.
     */
    public void setSvgResource(int svgResource) {
        svgResourceId = svgResource;
    }
    

    这里的setSvgResource只支持通过资源id加载,如果你需要用到其他的加载方式,比如assets、流等,那么你需要修改这个库,因为它也用到了上面提到的androidsvg库,后者是支持多种方式的。
    SVG.class

    public static SVG getFromInputStream(InputStream is) throws SVGParseException {
        SVGParser parser = new SVGParser();
        return parser.parse(is);
    }
    
    public static SVG getFromString(String svg) throws SVGParseException {
        SVGParser parser = new SVGParser();
        return parser.parse(new ByteArrayInputStream(svg.getBytes()));
    }
    
    public static SVG getFromResource(Context context, int resourceId) throws SVGParseException {
        return getFromResource(context.getResources(), resourceId);
    }
    
    public static SVG getFromResource(Resources resources, int resourceId) throws SVGParseException {
        SVGParser parser = new SVGParser();
        return parser.parse(resources.openRawResource(resourceId));
    }
    
    public static SVG getFromAsset(AssetManager assetManager, String filename) throws SVGParseException, IOException {
        SVGParser parser = new SVGParser();
        InputStream is = assetManager.open(filename);
        SVG svg = parser.parse(is);
        is.close();
        return svg;
    }
    

    所以如果要对这个库进行修改,你应该导入这个库模块。
    build.gradle

    //compile 'com.eftimoff:android-pathview:1.0.8@aar'
    compile project(':android-pathview')
    

    settings.gradle

    include ':android-pathview'
    
    20171009154547.png

    查看代码可以知道,这个库做的工作实际就是将svg图片的path解析成android的path,然后绘制出来,实现动画效果。

    关于动态加载

    可以通过下载svg图片,然后以流的方式读取,完成加载。

    参考资料

    Android动画机制与使用技巧(五)——Android 5.X SVG 矢量动画机制
    Android实现炫酷SVG动画效果

    相关文章

      网友评论

          本文标题:svg在android上的应用

          本文链接:https://www.haomeiwen.com/subject/rnpuyxtx.html