android图片系列 (2) - 静态 SVG 图片

android图片系列 (2) - 静态 SVG 图片,第1张

SVG 是一种可支持任意缩放的格式,使用 xml 定义,使用 canvas 中 path 路径来完成绘制,和我们传统使用的 BitMap位图有很大的区别。

SVG 在前端早就普及了,在android 中是 google 是在50之后开始支持的,14年出来之后兼容是个大问题,随着20162 V7包 2320版本的发布才算是有个相对完善的兼容使用方案。

SVG 的概念我就不写了,拿来主义啦,原文: Android Vector曲折的兼容之路

不瞎逼逼,我们先来看一看 android 中的 SVG 矢量图是个什么东东

看到没有,这就是一个 SVG 矢量,就是一个 xml 文件,右边是预览,先说下,这东西的好处:缩放不失真,体积小。这一个 SVG 只有970个字节强大吧,比 png 格式的强的没边了吧,png 我们还得适配,做多套,然后一个一个改名字复制到工程里,有了 SVG 妈妈再也不担心我们写作业啦

这里需要解释下这里的几个标签:

这里有一分详细的属性说明:

好了下面开始介绍 SVG 啦

首先,需要讲解两个概念——SVG和Vector。

SVG,即Scalable Vector Graphics 矢量图,这种图像格式在前端中已经使用的非常广泛了

Vector,在Android中指的是Vector Drawable,也就是Android中的矢量图

因此,可以说Vector就是Android中的SVG实现,因为Android中的Vector并不是支持全部的SVG语法,也没有必要,因为完整的SVG语法是非常复杂的,但已经支持的SVG语法已经够用了,特别是Path语法,几乎是Android中Vector的标配

Android以一种简化的方式对SVG进行了兼容,这种方式就是通过使用它的Path标签,通过Path标签,几乎可以实现SVG中的其它所有标签,虽然可能会复杂一点,但这些东西都是可以通过工具来完成的,所以,不用担心写起来会很复杂。

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 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):弧线

Z = closepath():关闭路径

坐标轴为以(0,0)为中心,X轴水平向右,Y轴水平向下

所有指令大小写均可。大写绝对定位,参照全局坐标系;小写相对定位,参照父容器坐标系

指令和数据间的空格可以省略

同一指令出现多次可以只用一个

注意,’M’处理时,只是移动了画笔, 没有画任何东西。 它也可以在后面给出上同时绘制不连续线。

关于这些语法,开发者需要的并不是全部精通,而是能够看懂即可,其它的都可以交给工具来实现。

这里有一篇 Android vector标签 PathData 画图超详解 详细描述了 SVG 中 path 的绘制

好了概念性的东西说完了,我们来看看

SVG 的使用分2种,一种是静态 SVG 矢量图,就是本文的主角,本章节主要谈论的东西,另一种是 SVG 矢量动画,是SVG 的高级应用,是给静态 SVG 加上objectAnimator 动画,应用的很广泛,是实现 android icon 动态交互的核心做法。

上面的SVG 图大家都看到了,我们就是写一个 xml 的文件,里面承载的标签都是描述如何绘制我们想要的图案的,画布大小,颜色,路径等,然后交给系统去绘制。

现在让我们来看看 SVG 在 andorid 中如何应用,如何兼容50以下版本。

SVG 虽然早早就在前端使用了,但是 android 上开始支持 SVG 的使用还是从50开始的,在50以上系统的使用很简单,和之前一样使用 PNG 一样

首先 android 中的 SVG 的承载方式是一个 xml 文件,所以UI 给我们的 SVG 是不能直接使用的,这里 google 给我们提供加载方式

Android studio 在 233 的版本中可以直接使用 svg,新建一个 SVGDemo项目,新建 Vector Asset 文件:app-> main -> New -> Vector Asset 如图所示:

我们选择 Local File 就是选择本地svg文件进行导入,对文件命名后点击 Next ->Finish 在 drawable目录 下就添加了一个xml的文件

好了这样一个 svg 我们算是加入到我们的工程里里了,可以直接使用了。当然在此之前我们把 SVG 放在那个 drawable 文件夹呢。对于这个问题就要说一下了:

有一点需要解释一下,svg 矢量图文件我们放在drawable 根目录即可。android 系统不会根据你把 svg 矢量图存放在不同的 drawable 文件夹,对进行分辨率上的缩放,因此我们不用像使用 PNG 时准备多套了。我们导入 SVG 默认存放的地址就是 drawable根目录,所以我们就放这里就好了,当然也可以自己写SVG ,都是 xml 的,自己写完 path 路径后都是可以查看预览的,一般也不会自己写,都是UI 的活。

这样就 ok啦,50以上的系统SVG你就像一般 png 一样使用就好啦,你可以试一下。

SVG 在 4x 版本上的兼容根据 SVG 使用范围的变化,配置也是逐步增加的

这时 imageview 就不行了,我们需要使用 AppCompatActivity 或是 AppCompatImageView,这时我们需要导入 V7 包

gradle 需要如下配置:

系统会在 4x 版本时对 SVG 自动生成相应的 drawable 图,此时 SVG 是没有无限拉伸特性的,gradle 的配置目的是去这个

举个例子:

资源设置不能用 src 了,必须使用 srcCompat ,这时我们能看到图而不是去 SVG 的特性了

这时上面的设置就不够了,我们在 view 所在的 activity 或是全局添加下面的设置

然后这还不够,我们必须给 SVG 添加一个容器,比如 selector,这样我们才能正常使用,比如给 textview 设置,自定义属性设置

这个 vc_halfstart_24dp 就是 SVG

这个我们必须要添加官方的 vectorDrawable 支持库了,最低支持到 2320

这样基本就没啥问题了

SVG 配合自定义 view 的话,就得我们读取 SVG 然后转换成 path 路径来画了,SVG 实质上也是 xml 文件,所以解析 xml 文件的思路也使用,当然还有其他一些 SVG 转 path 的思路

SVG前戏—让你的View多姿多彩 一文中提供了一些思路,大家不妨去看看

如何在页面中调用百度地图,直接在你想要插入的页面上调用百度地图代码即可

百度地图调用API地址:>

在之前的项目中需要用到D3来绘制可视分析视图,参考了一些例子之后,能够依葫芦画瓢。但是想要自己创作的时候却感受到了技术上的瓶颈。以我对D3粗浅的理解,认为其是基于SVG的lib,即D3中图像的绘制的基础就是SVG,工欲用D3,必先理解SVG。遂决定先补一补SVG的知识。讲的不会很具体,主要是概念上的东西。

接下来主要涉及到的有:

栅格化的图像则是把原来一个像素点放大,这样会导致放大之后的糊啦。而svg是矢量图,矢量图就是不论放大多少倍,他都不会变形变模糊。这是怎么做到的呢?来自于矢量图的放大就是把形状坐标的值按倍数变大,重新绘制就完事了。所以说,svg绘制的关键就在于坐标点的确定。当我在画一个svg的时候,我其实要找的就是能够确定这个svg图像的坐标点。

画画要纸,画SVG则要画布。画布就是这个SVG元素。 width 和 height 的指定单位可以是 px em 百分比 。

画布有一个默认的坐标系。

绘制的时候,如果遇到了需要旋转、缩放、移动的情况。其实并不是对元素本身的坐标进行计算然后改变,而是将元素的坐标系进行变换,变换完毕之后,在新的坐标系去绘制图像。这样做的好处是让数学计算变得更加简单。毕竟坐标系可以近似看作一个长方形,变换起来计算量并不会太大,相反,如果是对图形变换,绘制一个奇形怪状的东西,则对每一个坐标进行变换计算,就非常可怕了(类似一个复合函数的计算,为了简化先算外层再算内层一般)。

path 就相当于你画的每一笔。绘制的过程就是行笔的过程。笔的连线由坐标点去控制。

一些常用的图形如 circle rect line 等,是可以直接使用的,只要给它设置了它接受的参数。

贝塞尔曲线对于熟悉Illustrator的人来说并不会陌生。svg是支持画两次贝塞尔曲线(一个控制点)与三次贝塞尔曲线(两个控制点)的。这就给画出“优雅”的图形成为可能。

最后放一篇今天读到的很好的文章: How do you learn d3 这篇文章总结了几位擅长数据可视化的学习经验:学习d3应该是目标导向的,先知道自己要画的是什么,然后再去学习怎么画。这也给我的学习可视化的方法上提供了思路:不必追求把D3的api看的滚瓜烂熟,D3不过是一个用于实现的设计的工具。

1、可缩放矢量图形(Scalable Vector Graphics,SVG)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式。SVG由W3C制定,是一个开放标准。

2、如果想将svg图转化为png,pdf,tiff格式的位图,只需将上面命令行参数jpg改为png,pdf,tiff即可。

3、打开SVG图像浏览器

java -jar "d:\Program Files\batik-17\batik-squigglejar"

4、Java Development Kit (JDK) 是Sun公司针对Java开发员的产品。自从Java推出以来,JDK已经成为使用最广泛的Java SDK(Software development kit)。

viewport 很好理解,就是类似我们的电视机,我们只能通过看到电视机里边的内容,却无法看到电视画面外边的画面。

viewbox是什么呢,你去看文档会有很多答案,但是我觉得把握一个最基本的概念就可以,

viewbox就是最后我们画图的坐标系统,也就是说我们在svg上画东西的时候,就是根据viewbox的坐标系统,来确定最后的位置的。

viewbox为什么这么难理解?

其实看了好多文章,根本都模糊不清楚,看svg精髓这本书里边说的也是云里雾里,不知所云

我觉得可以从以下几点进行理解

viewbox的定义

当viewbox的宽高比和viewport的宽高比相同的时候,首先是设置用户坐标,然后绘图

宽高比相同指的是 svg设置的width:height 与 viewbox设置的 width:height 相等

比如

这里的svg的宽高比是400: 200 = 2

viewbox设置的宽高比是 200: 100 = 2

所以这里的宽高比是一样的

表现如下

渲染过程

svg的viewport的宽高分别是800 和600

viewbox的设置宽高 分别是 0 0 800 600

这里所以用户的坐标是1:1 也就是用户坐标的一像素对应viewport的1像素

所以结果如图

表现如下

渲染过程

svg的viewport 宽高依然是800和600

viewbox的宽高比变成0 0 400 300

这里的一步首先是确定用户坐标,因为设置的用户坐标是400 300 ,但是实际的viewport是800和600,所以对应起来就是用户坐标的1像素对应viewport的二像素

所以 当绘制图像的时候,原来在用户坐标100, 100的点,在viewbox 是 0 0 800 600的时候,对应的viewport的物理像素是100,100的点,但是到了viewbox是 0 0 400 300的时候,用户坐标100, 100的点,对应的物理像素变成了200, 200的点了,所以整个图像变大了

这里注意的是绘制图像的坐标始终是没有变,原来是100,100 还是100,100,变化的是用户坐标到svg的viewport的转换变化了。

上面介绍了viewbox的width和height,在宽高比和viewport相同的时候的情况,现在介绍还是在宽高比和viewport相同的时候的情况下,设置viewbox的x和y是如何变化的。

其实原理是一样的,还是分成两个步骤

a, 首先设置用户坐标,也就是用户坐标到svg viewport的转换关系,

b, 绘制图像

表现如下

可以看到图像向左移动了150px

原理还是按照上面的两步

1, 首先设置用户坐标,这里是svg的是800 : 600 ,而viewbox的也是800:600

所以这里是用户坐标到实际是1:1,然后因为设置了viewBox 的x是150,所以这里的用户坐标会向左移动150,所以原来绘制在用户坐标范围从(0, 0)到(150,0)的就无法显示出来了。

当宽高不相同的时候,就首先得有个标准,也就是根据什么来设置用户坐标到viewport的转换,也就是preserveAspectRatio

这个说半天也不好理解,不如直接看实际的效果图

>

java总字符串转换成其他基本数据类型的方式,可以使用基本数据类型的toString()方法,还有String类型转换成其他的基本数据类型,示例如下:

Integer I1=new Integer(i1);//生成Integer类

Float F1=new Float(f1); //生成Float类

Double D1=new Double(d1); //生成Double类

//分别调用包装类的toString() 方法转换为字符串

String si1=I1toString();

String sf1=F1toString();

Stringsd1=D1toString();

Sysytemoutprintln("si1"+si1);

Sysytemoutprintln("sf1"+sf1);Sysytemoutprintln("sd1"+sd1);

String MyNumber ="1234";

int MyInt = IntegerparseInt(MyNumber);

字符串转换成byte, short, int, float, double, long 等数据类型,可以分别参考Byte, Short,Integer, Float, Double, Long 类的parseXXX 方法。

以上就是关于android图片系列 (2) - 静态 SVG 图片全部的内容,包括:android图片系列 (2) - 静态 SVG 图片、echarts自定义SVG地图后怎么通过真实经纬度进行标注、帮助理解D3的SVG基础知识等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9689017.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存