矢量图形在移动应用上的优势
矢量图形与光栅格式图像相比,在对动画、地图和互动图形进行编码和显示方面的优势是明显的。矢量图形是动态的、可以缩放的,能够描述非常高级的图形特性,如复杂形状、动画、分层图形和特殊效果等。
利用矢量图形的缩放性,图形可以调整大小,以适应任何显示设备而不会导致品质损失。这在移动设备上是一个优势,因为移动设备的显示屏的形状、尺寸和分辨率差别很大。矢量图形还可以很方便的进行平移、缩放、旋转以及与用户交互的操作,因此用户可以在不影响图形质量的情况下对图形进行放大,这在使用手机的小屏幕看图时特别有用。
矢量图形文件通常小于光栅图像文件,从而可以缩短无线下载时间,这点对于非常计较带宽的移动应用来说尤其重要。另外,将当前屏幕上的图形放大时,对于光栅图像会出现使图像模糊的马赛克效应,此时若要获得高质量的放大图像,则需重新从服务器获取放大后的图像,从而增加了网络的流量,而矢量图形在客户端进行放大就可以得到没有质量损失的放大图形。
矢量图形的另一个强大功能是可以存储图形中各元素的相关信息。例如,通过对建筑矢量图形的附加数据,就可以知道房间的面积,售价等信息。
最后,矢量图形可以方便的利用搜索引擎对图形中的属性进行搜索,实现基于图形的数据搜索。
目前在移动领域的矢量应用主要包括FlashLite和Mobile SVG等,本文主要讨论Mobile SVG。
Mobile SVG标准
SVG(Scalable Vector Graphics,可缩放矢量图像)是互联网联盟(W3C)的正式推荐标准,它是一种使用XML来描述二维图像的语言。由于SVG的大部分特性非常适合于无线领域的图形应用,为了满足移动业界的需求, W3C的SVG工作小组制订了适合于移动应用领域的Mobile SVG标准。
Mobile SVG主要用于各种资源非常有限的移动设备,所以在实现Mobile SVG时,性能指标成为最主要的指标。由于移动设备在CPU速度、内存大小、支持的显示颜色等各个参数上有很大的不同,单一的专业标准很难满足所有移动设备的要求。因此,为了覆盖不同移动设备家族的需求,SVG工作小组最终制订了两个级别的Mobile SVG专业标准。一种专业标准是SVG Tiny (SVGT),适用于资源高度受限的移动设备,如手机;另一种专业标准是SVG Basic (SVGB),适用于高端的移动设备,如PDA等。由于移动设备硬件条件的限制,相对于标准的SVG,Mobile SVG在支持的内容、属性、功能等方面作了限制。SVGB是标准SVG的子集,而SVGT又是SVGB的子集,SVGT标准中删除了透明、渐变、裁剪、图案、符号和蒙板等复杂功能,而且没有对脚本支持。具体的不同请参考W3C SVG网址。
以下是一个SVGT的例子:
<?xml version="1.0" encoding="utf-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:demo="http://www.sun.com/svg/demo" id="root" width="100%" height="100%" viewBox="0 0 240 320" xml:space="preserve" preserveAspectRatio="none"> <rect fill="#35556B" width="240" height="320"/> <g id="processingIndicator" transform="translate(120, 97) scale(0.5)" > <g id="processingIndicator.outerCircle"> <path transform="translate(-120, -97)" fill="#C1CBD1" d="M73.426,97.169c0,25.681,20.894,46.575,46.575,46.575c25.681,0,46.574-20.894,46.574-46.575c0-9.251-2.708-18.192-7.83-25.854c-1.688-2.525-5.104-3.204-7.629-1.516s-3.204,5.104-1.516,7.629c3.908,5.847,5.975,12.673,5.975,19.741c0,19.616-15.959,35.575-35.574,35.575c-19.616,0-35.575-15.958-35.575-35.575c0-19.616,15.959-35.575,35.575-35.575c6.063,0,12.048,1.551,17.307,4.485c2.652,1.48,6.002,0.53,7.482-2.123c1.48-2.653,0.529-6.003-2.123-7.483c-6.893-3.846-14.73-5.879-22.666-5.879C94.319,50.594,73.426,71.488,73.426,97.169z"/> </g> <g id="processingIndicator.innerCircle"> <path transform="translate(-120, -97)" fill="#738999" d="M120.001,69.772c-5.441,0-10.701,1.592-15.21,4.607c-2.525,1.688-3.204,5.104-1.516,7.629c1.688,2.525,5.104,3.204,7.629,1.516c2.693-1.8,5.838-2.752,9.096-2.751c4.38,0,8.498,1.705,11.594,4.802c3.098,3.097,4.803,7.214,4.803,11.594c0,9.042-7.355,16.397-16.397,16.397c-9.041,0-16.396-7.355-16.396-16.397l0.065-1.479c0.134-3.034-2.201-5.848-5.236-5.981c-3.034-0.134-5.587,1.972-5.721,5.007l-0.108,2.454c0,15.107,12.29,27.397,27.396,27.397c15.107,0,27.397-12.291,27.397-27.397c0-7.318-2.85-14.198-8.024-19.373S127.318,69.772,120.001,69.772z"/> </g> <g id="processingIndicator.center" > <circle fill="white" transform="translate(-120, -97)" cx="120" cy="97.169" r="9.349"/> <circle display="none" fill="#35556B" transform="translate(-120, -97)" cx="122.321" cy="92.551" r="2.078"/> </g> </g> <defs> <animateTransform id="processingIndicatorAnim" xlink:href="#processingIndicator.innerCircle" attributeName="transform" type="rotate" values="0;360" begin="0s" dur="3s" repeatDur="indefinite"/> <animateTransform xlink:href="#processingIndicator.outerCircle" attributeName="transform" type="rotate" values="0;-360" begin="0s" dur="2s" repeatDur="indefinite"/> <animateTransform xlink:href="#processingIndicator.center" attributeName="transform" type="rotate" values="0;-360" begin="0s" dur="1s" repeatDur="indefinite"/> </defs> <g id="loadProgressBar"> <rect id="loadProgressBar.bkg" fill="#A3B8CB" x="45" y="250" width="150" height="10" /> <rect id="loadProgressBar.progress" fill="white" x="45" y="250" width="20" height="10" /> <text transform="translate(120,230)" fill="#BDBEC0" font-size="12" text-anchor="middle">loading application</text> <text id="loadProgressBar.text" text-anchor="middle" transform="translate(120,275)" fill="#FFFFFF" font-size="12">0%</text> </g> </svg> |