关于Android中使用SVG特性的探索与总结

前言

引入SVG还需要从图片的数字化说起。一般来说,将图片存储为数据有两种方案。其一、就是我们传统使用的位图(光栅图)。即将图片看成在平面上密集排布的点的集合。每个点发出的光有独立的频率和强度,反映在视觉上,就是颜色和亮度。位图拥有一个庞大的家族,包括常见的JPEG/JPG, GIF, TIFF, PNG, BMP等。第二种方案就是矢量图(SVG就是其中的一种)。它用抽象的视角看待图形,记录其中展示的模式而不是各个点的原始数据。它将图片看成各个“对象”的组合,用曲线记录对象的轮廓,用某种颜色的模式描述对象内部的图案(如用梯度描述渐变色)。比如一张留影,被看成各个人物和背景中各种景物的组合。这种更高级的视角,正是人类看世界时在意识里的反映。矢量图格式有CGM,
SVG, AI (Adobe Illustrator), CDR (CorelDRAW), PDF, SWF, VML等等。

矢量图中简单的几何图形,只需要几个特征数值,就可以确定。比如三角形,只需要确定三个顶点的坐标。圆只需要确定圆心的坐标和半径。描述它的函数已知的曲线也只需要几个参数就能够确定。如正弦曲线、各种螺线等等。如果用位图记录这些几何图案,则需要包含组成线条的各个像素的数据。除了大大节省空间,矢量图还具有完美的伸缩性。因为记录的是图形的特征,图形的尺寸任意变化时,都只是做着相似变换,不会出现模糊和失真。相反,位图的图片放大到超出原有大小时,各个像素点之间出现空缺,即使用某种算法填充,也会出现模糊锯齿等现象,不如矢量图精确。因而矢量图很适合用于记录诸如符号、图标等简单的图形。而位图则适合于没有明显规律的、颜色丰富细腻的图片。

说起SVG可能有些人不怎么熟悉,但提及xml,对于大部分人来说都是耳熟能详的。其实,SVG也就是使用xml定义的图形。当然,主流的解析xml的工具一般都可以拿来解析svg。SVG是从Android5.0版本开始被引入到Android平台上的。下面我就SVG的话题,根据我这段时间的探索进程一一展开。

一、SVG简介

根据网络上的定义:SVG是可缩放矢量图形,是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式。它由万维网联盟制定,是一个开放标准。

SVG的优势

首先简要解释一下矢量图像格式和位图图像格式的区别。矢量图像用点和线来描述物体,所以文件会比较小,同时也能提供高清晰的画面,适合于直接打印或输出。而位图图像的存储单位是图像上每一点的像素值,因此一般的图像文件都很大,会占用大量的网络带宽。SVG是一种矢量图形格式,GIF、JPEG是光栅文件格式。有了两者的概念后,SVG较GIF、JPEG的优势显而易见。

任意放缩

用户可以任意缩放图像显示,而不会破坏图像的清晰度、细节等。

文本独立

SVG图像中的文字独立于图像,文字保留可编辑和可搜寻的状态。也不会再有字体的限制,用户系统即使没有安装某一字体,也会看到和他们制作时完全相同的画面。

较小文件

总体来讲,SVG文件比那些GIF和JPEG格式的文件要小很多,因而下载也很快。

超强显示效果

SVG图像在屏幕上总是边缘清晰,它的清晰度适合任何屏幕分辨率和打印分辨率。

超级颜色控制

SVG图像提供一个1 600万种颜色的调色板,支持ICC颜色描述文件标准、RGB、线X填充、渐变和蒙版。

交互和智能化

SVG面临的主要问题一个是如何和已经占有重要市场份额的矢量图形格式Flash竞争的问题,另一个问题就是SVG的本地运行环境下的厂家支持程度。

二、SVG的解析

上文提到Android5.0时引入了SVG特性,其中必然会涉及到SVG图片的加载与解析。而svg本质上就是xml文件,所以从解析角度来看,能解析xml文件的工具应该几乎都可以用来解析svg文件。

1、DOM解析

查看Android源码可以看出,5.0引入svg后并没有使用dom进行解析svg源文件,虽然svg号称完全支持dom标准。笔者从dom解析的过程可以看出,Dom解析是将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件。虽然一般情况下,svg文件是比较小的,但也不乏有些很复杂的图片会上升到M级别,如果在解析时需要全部载入,对于Android系统来说时比较耗时的,这也许就是dom遭Android淘汰的原因之一吧。

2、SAX解析

SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用

3、PUll解析

PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像 SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使 用,Android系统内部在解析各种XML时也是用PULL解析器

三、SVG在Android5.0以上版本中的使用

1、使用方法

鉴于SVG有那么多的优点,Android于5.0版本将该特性引入。在5.0以上版本中使用方法如下:

1)获取SVG图片数据

第一种方法当然是从网上down了(一般直接用来测试使用),这里只给出几个常用素材下载网站:

http://sc.chinaz.com/

http://www.freevectors.net

http://www.freevectordownload.com/

其次就是手工制作了:真正做项目时,方法1肯定满足不了相应的需要了。这时我们只能自己动手来作图了(应该是美工来负责^_^||),相应最常用的软件就是PS、AI或者CDR也可以。具体制作方法这里就不做介绍了,直接上网搜就行。这里给出一个较为详细的例子:http://blog.csdn.net/tianjian4592/article/details/44733123

2)将普通SVG图片数据转换成Android可用数据

一般的SVG图片数据是直接在html或jsp中可以使用,Android中若想使用svg则需要中间环节先转换成Vector标签包括的xml文件(如果做动画的话,外面还需要包括一层animated-vector来引用vector资源),其中最重要的就是path元素,该元素就是图片加载显示过程中的绘制轨迹。具体转换方法网上查询得出有两种:一是手动改写,二是直接使用自动转化工具转换(http://inloop.github.io/svg2android/)。具体转换规则以及相应符号意义可以参见:http://www.w3.org/TR/SVG11/paths.html#PathData.

3)在工程中使用

svg在5.0以上的Android工程中使用相对较为简单,直接用drawable控件(如mageView等)引用第二步中转换得来的xml文件资源即可。

2、Demo实例

实例一:mytest(使用Drawable控件引用5.0新特性vector资源)

【关键代码摘要】

使用vector标签包括path元素

[ sharp_rect.xml ]

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="180dp"
    android:height="320dp"
    android:viewportWidth="180"
    android:viewportHeight="400">

    <path
        android:name="sharp_rect"
        android:fillColor="#000000"
        android:pathData="M 320,180 L 0,320 0,0 180,0 z" />
</vector>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

使用ImageView引用vector资源sharp_rect

[ activity_main.xml ]

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <ImageView
        android:src="@drawable/sharp_rect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Demo附件: mytest.zip

效果图:

实例二:【VectorCard】使用5.0新特性animated-vector标签引用xml中的svg path元素

【关键代码摘要】

[ to_stop.xml ]

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                android:duration="500"
                android:interpolator="@android:interpolator/decelerate_cubic"
                android:propertyName="pathData"
                android:valueType="pathType"
                android:repeatMode="reverse"
                android:repeatCount="1"
                android:valueFrom="M100,100 L400,250 L100,400 L100,400 z"
                android:valueTo="M100,100   L400,100 L400,400 L100,400 z" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

[ animated_play.xml ]

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
                 android:drawable="@drawable/play_icon">
    <target
        android:animation="@animator/to_stop"
        android:name="play" />
</animated-vector>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Demo附件: app.zip

效果图:

3、小结

Android5.0关于这块新特性的添加主要是依赖于Vctor,对应的类为VectorDrawable以及AnimatedVectorDrawable。前者主要用于矢量图的加载,后者主要用于矢量动画的加载。二者在使用过程中要区分对待。

四、Android5.0以下使用SVG探索总结

经过这短时间的不断摸索与实验,按照svg_android组织的方法主要有以下两种:

1、基于svg_android库

抽取类似svg_android库中适合5.0以下的,且可以解析svg的Java文件,自定义类似svg的控件,进行Android工程的搭建(该实例使用sax解析svg文件)。

对应实例:【SVGMapView-master】

Demo附件: SVGMapView-master.zip

效果图:

【说明】 该方法需要开发者自己去重写解析函数,目前该实例并不能支持所有的svg语法的解析,如将该方法布置到项目中,需要大量拓展解析甚至加载SVg的功能函数。

2、基于JNI技术

加载及加息svg的工作交给C/C++处理,上层使用java调用对应.so库暴露的接口。

对应实例:【ImageViewSvg】

Demo附件: ImageViewSvg.zip

效果图:

【说明】该方案虽然使用了JNI技术来加载并解析svg文件,但目前其解析度有限,功能较为单一,如需要布置该方案于项目中,对于jni侧也需要扩展大量的svg解析函数。且需要优化对应的加载处理环节。

五、总结

从整体上看,目前是有可能将svg应用到Android5.0以下版本的。但其的稳定性,以及后续的工作量是需要我们仔细斟酌的问题之一。

时间: 2024-10-15 19:06:33

关于Android中使用SVG特性的探索与总结的相关文章

Android动画机制与使用技巧(五)——Android 5.X SVG 矢量动画机制

Google在Android 5.X 中增加了对SVG 矢量图形的支持,这对于创建新的高效率动画具有非常重大的意义.那首先了解SVG的含义. 可伸缩矢量图形(Scalable Vector Graphics) 定义用于网络的基于矢量的图形 使用XML格式定义图形 图像在放大或改变尺寸的情况下其图形质量不会有所损失 万维网联盟的标准 与诸如DOM和XSL之类的W3C标准是一个整体 SVG在Web上的应用非常广泛,在Android 5.X之前的Android版本上,可以通过一些第三方开源库来在And

探索Android中的Parcel机制(上)

一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等. 二.Android中的新的序列化机制 在Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中採用了新的IPC(进程间通信)机制,必定要求使用性能更出色的对象传输方式.在这种环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列

探索Android中的Parcel机制(下)

上一篇中我们透过源码看到了Parcel背后的机制,本质上把它当成一个Serialize就可以了,只是它是在内存中完成的序列化和反序列化,利用的是连续的内存空间,因此会更加高效. 我们接下来要说的是Parcel类如何应用.就应用程序而言,最常见使用Parcel类的场景就是在Activity间传递数据.没错,在Activity间使用Intent传递数据的时候,可以通过Parcelable机制传递复杂的对象. 在下面的程序中,MyColor用于保存一个颜色值,MainActivity在用户点击屏幕时将

android竖向显示新特性界面

腾讯手机管家,初始界面有个小飞机动啊动啊,还挺好玩的,而且显示新特征为竖向展示,不知道这种东西该如何实现呢?给自己留下比较深的印象,然后楼主就是探索这种是如何实现的. 看着很不错,显示特征为竖向,增加小火箭的动态感,兼具金秀贤的帅气,简单.明确.有特点. 我得目的: 1.实现显示新特征的竖向. 2.增加动态箭头的动感. 3.颜色采用小清新 一个自定义的ViewPager可以搞定,引用自JakeWharton的一个开源项目:点击打开链接,同时借鉴了weidi1989的Android之仿网易V3.5

Android 6.0+ 运行时权限探索

原创文章,转载请注明 ( 来自:http://blog.csdn.net/leejizhou/article/details/51511630 李济洲的博客 ) 引言:去年Android 6.0发布后,其新引入的(Requesting Permissions at Run Time)运行时权限就备受开发者关注,随着今年国内手机厂商对6.0系统的普及,觉得大家有必要了解下这个新特性,因为在TargetSDK23+进行开发不注意这些会造成APP运行在6.0+手机上崩溃,这篇博文将对这个新特性进行探索

【转】Android中的内存管理--不错不错,避免使用枚举类型

原文网址:http://android-performance.com/android/2014/02/17/android-manage-memory.html 本文内容翻译自:http://developer.android.com/training/articles/memory.html 随机存取存储器(RAM)再任何软件开发环境中都是宝贵的资源,但是在移动操作系统中,内存资源更为宝贵,使用时也会收到限制.虽然Android的Dalvik虚拟机有运行时的垃圾回收机制,但是这不意味着你的A

Android中关于View滑动的实现你应该知道的

滑动作为Android中最基础的特效之一,使用场景非常广泛.实现的方式也有多种,理解各种滑动的实现方式.清楚在开发中根据自己的实际需求,选择合理的实现方案.这篇文章从:scrollTo()/scrollBy()内容滑动|动画方式滑动|修改布局参数,三种方式来做简要的分析. 一丶scrollerTo()&&scrollBy()内容滑动 这两个方法都是View自带的滑动方法,即每个控件都可以通过调用这两个方法实现滑动.scrollBy()方法的实现本质也是调用scrollTo()方法,不同之处

Android中View滑动实现方式

滑动作为Android中最基础的特效之一,使用场景非常广泛.实现的方式也有多种,理解各种滑动的实现方式.清楚在开发中根据自己的实际需求,选择合理的实现方案.这篇文章从:scrollTo()/scrollBy()内容滑动|动画方式滑动|修改布局参数,三种方式来做简要的分析. 一丶scrollerTo()&&scrollBy()内容滑动 这两个方法都是View自带的滑动方法,即每个控件都可以通过调用这两个方法实现滑动.scrollBy()方法的实现本质也是调用scrollTo()方法,不同之处

分析Android中View的工作流程

在分析View的工作流程时,需要先分析一个很重要的类,MeasureSpec.这个类在View的测量(Measure)过程中会用到. MeasureSpec MeasureSpec是View的静态内部类,可以理解为是一种测量规格,是一个32位int值,高2位代表SpecMode,低30位代表SpecSize,SpecMode是指测量模式,而SpecSize是指在某种测量模式下的规格大小.SpecMode有三种模式,分别为: UNSPECIFIED:父容器不对View做限制 EXACTLY:父容器