背景
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
矢量图很适合用于记录诸如符号、图标等简单的图形。而位图则适合于没有明显规律的、颜色丰富细腻的图片。
SVG教程、jpg,png图片在线转svg、svgeditor
应用
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-svg、Glide从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动画效果
网友评论