多媒体图片的基本概念
- 矢量图像(消耗CPU,不占内存):SVG是W3C 推出的一种开放标准的文本式矢量图形描述语言,他是基于XML的、专门为网络而设计的图像格式,SVG是一种采用XML来描述二维图形的语言,所以它可以直接打开xml文件来修改和编辑。
- 位图图像(不消耗CPU,占内存):位图图像(BitMap)的存储单位是图像上每一点的像素值,因而文件会比较大,像GIF、JPEG、PNG等都是位图图像格式。
SVG
SVG,即Scalable Vector Graphics 可伸缩矢量图形,这种图像格式在前端中已经使用的非常广泛了。
SVG的W3C的解释: http://www.w3school.com.cn/svg/svg_intro.asp
Android中使用SVG
Android中通过Vector使用SVG,在Android中指的是Vector Drawable,也就是Android中的矢量图,SVG的阉割版。可以说Vector就是Android中的SVG实现(并不是支持全部的SVG语法,现已支持的完全足够用了)
补充:Vector图像刚发布的时候,是只支持Android 5.0+的,自从AppCompat 23.2之后,Vector可以使用于Android 2.1以上的所有系统,只需要引用com.android.support:appcompat-v7:23.2.0以上的版本就可以了。(所谓的兼容也是个坑爹的兼容,即低版本非真实使用SVG,而是生成PNG图片(AS编译打包的时候自动生成))
Vector Drawable基本简介
Android 5.0发布的时候,Google提供了Vector的支持,即:Vector Drawable类。
优势
Vector Drawable相对于普通的Drawable来说,有以下几个好处:
- Vector图像可以自动进行适配,不需要通过分辨率来设置不同的图片。
- Vector图像可以大幅减少图像的体积,同样一张图,用Vector来实现,可能只有PNG的几十分之一。
- 使用简单,很多设计工具,都可以直接导出SVG图像,从而转换成Vector图像 功能强大。
- 不用写很多代码就可以实现非常复杂的动画 成熟、稳定,前端已经非常广泛的进行使用了。
基本语法
通过使用它的Path标签,几乎可以实现SVG中的其它所有标签,虽然可能会复杂一点,但这些东西都是可以通过工具来完成的,所以,不用担心写起来会很复杂。
Path指令解析如下所示:
M = moveto(M X,Y) :将画笔移动到指定的坐标位置,相当于 android Path 里的moveTo()
L = lineto(L X,Y) :画直线到指定的坐标位置,相当于 android Path 里的lineTo()
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 curve(Q X,Y,ENDX,ENDY):二次贝赛曲线
T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射 同样二次贝塞尔曲线,更平滑
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线 ,相当于arcTo()
Z = closepath():关闭路径(会自动绘制链接起点和终点)
注意,’M’处理时,只是移动了画笔, 没有画任何东西。
Tips
- 关于这些语法,开发者不需要全部精通,而是能够看懂即可,这些path标签及数据生成都可以交给工具来实现。
(一般美工来帮你搞定!PS、Illustrator等等都支持导出SVG图片) - 程序员:没必要去学习使用这些设计工具,开发者可以利用一些工具,自己转换一些比较基础的图像,
如:http://inloop.github.io/svg2android/ - 还可以使用SVG的编辑器来进行SVG图像的编写,例如:http://editor.method.ac/
(绝配!可以先用http://editor.method.ac/ 生成SVG图片,然后用http://inloop.github.io/svg2android/ 生成 VectorDrawable xml代码) - 使用AndroidStudio插件完成SVG添加(Vector Asset Studio)
详细:http://www.jianshu.com/p/d6c39f2dd5e7
AS会自动生成兼容性图片(高版本会生成xxx.xml的SVG图片;低版本会自动生成xxx.png图片) - 有些网站可以找到SVG资源
SVG下载地址: http://www.shejidaren.com/8000-flat-icons.html
http://www.flaticon.com/
例子--静态Vector
我们可以到http://editor.method.ac/画一张SVG,然后通过http://inloop.github.io/svg2android/转换成Android支持的xml。
这里为了方便,我直接到http://www.flaticon.com/找一张SVG图片,然后通过Android Studio进行转换,具体操作如下:
选中Drawable目录,右击,选择创建Vector Asset:
选择电脑中的SVG图片,确定,这里可以做一些简单的编辑,最后点击完成:
生成的xml如下:
解释头部的几个标签:
- android:width \ android:height:定义图片的宽高
- android:viewportHeight \ android:viewportWidth:定义图像被划分的比例大小,例如例子中的500,即把200dp大小的图像划分成500份,后面Path标签中的坐标,就全部使用的是这里划分后的坐标系统。
这样做有一个非常好的作用,就是将图像大小与图像分离,后面可以随意修改图像大小,而不需要修改PathData中的坐标。
最后,使用图片,就当普通的图片使用就可以了。当然也可以当作selector使用等:
这时候你会发现,使用SVG图片之后,无论ImageView放大还是缩小,都没有失真了。但是SVG画出来的一般都是一些比较扁平、简单的图片。
例子--动态Vector
动态Vector才是Android Vector Drawable的精髓所在,下面以搜索条为例子进行介绍:
首先画一个搜索条(drawable目录):
searchbar.xml:
添加动画(drawable目录):
searchbar_anim.xml:
其中,drawable是指定哪个SVG图片,target是指定动画
anim_searchbar_in、anim_searchbar_out的定义如下(animator目录):
anim_searchbar_in.xml:
anim_searchbar_outxml:
最后,在ImageView中使用:
注意:这种Animator只支持5.0+,低于这个版本会崩溃,存在兼容性问题。
SVG图片的性能问题
- Bitmap的绘制效率并不一定会比Vector高,它们有一定的平衡点,当Vector比较简单时,其效率是一定比Bitmap高的,所以,为了保证Vector的高效率,Vector需要更加简单,PathData更加标准、精简,当Vector图像变得非常复杂时,就需要使用Bitmap来代替了
- Vector适用于ICON、Button、ImageView的图标等小的ICON,或者是需要的动画效果,由于Bitmap在GPU中有缓存功能,而Vector并没有,所以Vector图像不能做频繁的重绘
- Vector图像过于复杂时,不仅仅要注意绘制效率,初始化效率也是需要考虑的重要因素
参考资料:
微信引入的SVG技术:
http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=207863967&idx=1&sn=3d7b07d528f38e9f812e8df7df1e3322&scene=4#wechat_redirect
如果觉得我的文字对你有所帮助的话,欢迎关注我的公众号:
我的群欢迎大家进来探讨各种技术与非技术的话题,有兴趣的朋友们加我私人微信huannan88,我拉你进群交(♂)流(♀)。