Android中使用SVG矢量图打造多边形图形框架

Android中使用SVG矢量图打造多边形图形框架#

最后要实现的最终效果如下图:


1.准备工作

(1) 因为项目中需要用到SVG矢量图,所以我们就需要一个将SVG图像转换为Bitmap的工具类:

CSDN资源下载[jar包]:http://www.123.com

Github源码下载:https://github.com/pents90/svg-android

如果下载的jar包直接在项目中引用就行,如果是源码只需要将源码放在项目中的包下即可,看看我AndroidStudio项目中源码文件:

(2) 准备SVG矢量图片,不清楚SVG图片的童鞋可以到W3CSchool上面去了解下; 如果找不到SVG矢量图的素材可以在 SVG在线编辑 上自己编辑一个SVG图片。###

准备好的SVG图片可以放在 res/raw 中(没有就手动创建),也可以放在项目的asset中(没有手动创建)

目录 对应获取SVG图片的方法
raw SVGParser.getSVGFromInputStream()
asset SVGParser.getSVGFromAsset()

2.SVG加载到Android中

现在开始正式撸代码 首先在项目中创建一个工具类:SvgBitmapUtils

在类中创建静态方法getSvgBitmap

    /**
     * 主要是用来加载SVG矢量图片,最后转换成我们属性的Bitmap格式
     * @param context
     * @param width SVG图片的宽
     * @param height SVG图片的高
     * @param resId SVG图片的ID
     * @return Bitmap
     */
    public static Bitmap getSvgBitmap(Context context , int width,int height ,int resId){
        //1.创建一个空的图片
        Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
        //2.拿到空图片的画布:目前来讲相当于一张白纸
        Canvas canvas = new Canvas(bitmap);
        //创建一直画笔
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setDither(true);//防止画笔抖动
        paint.setColor(Color.BLACK);//画笔颜色为黑色'

        //当传入的id是一个正常的ID
        if (resId>0){
            // 3.通过SVGParser来加载一个SVG图片
            // 加载raw目录下的SVG文件
            SVG svg = SVGParser.getSVGFromInputStream(context.getResources().openRawResource(resId),width,height);
            // 4.将通过svg对象的getPicture()方法得到一个Picture对象,然后将Picture画在画布上
            canvas.drawPicture(svg.getPicture());
        }else {
            //如果没有找到SVG图片就画一个矩形
            canvas.drawRect(new Rect(0,0,width,height),paint);
        }

        return bitmap;
    }

接下来是Svg图片与妹子的合并,所以首先准备一张妹子图,因为我们合并和得到一张正方形的合并图片,所以要先根据给定的妹子图得到合并后图片的宽(size),很明显就是妹子图片的宽或高中最小的一边的长度:

int size = Math.min(fg.getWidth(),fg.getHeight());

然后根据这个宽(size)从妹子的原图中切出一张正方形图片,从原图中切出一个正方形图片需要知道切图的起始位置(<font color="#ff3456">相对与图片的左上角的位置:x,y</font>)

    //2.确定截取正方形左上角的坐标
    int x = (fg.getWidth()-size)/2;
    int y = (fg.getHeight()-size)/2;

有了开始的Svg矢量图和现在切出来的妹子图;就可以开始合并图片,可是要怎么样才能合并出上面的那样的效果;

先来看看官方给出图片合并模式 来自ApiDemos/Graphics/XferModes):

从上图可以看到PorterDuff.Mode为枚举类,一共有16个枚举值:

枚举值 对应效果
1.PorterDuff.Mode.CLEAR 所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC 显示上层绘制图片。
3.PorterDuff.Mode.DST 显示下层绘制图片。
4.PorterDuff.Mode.SRC_OVER 正常绘制显示,上下层绘制叠盖。。
5.PorterDuff.Mode.DST_OVER 上下层都显示。下层居上显示。。
6.PorterDuff.Mode.SRC_IN 取两层绘制交集。显示上层。。
7.PorterDuff.Mode.DST_IN 取两层绘制交集。显示下层。。
8.PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分。。
9.PorterDuff.Mode.DST_OUT 取下层绘制非交集部分。。
10.PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分。
11.PorterDuff.Mode.DST_ATOP 取上层非交集部分与下层交集部分。
12.PorterDuff.Mode.XOR 所异或:去除两图层交集部分。
13.PorterDuff.Mode.DARKEN 取两图层全部区域,交集部分颜色加深。
14.PorterDuff.Mode.LIGHTEN 取两图层全部,点亮交集部分颜色。
15.PorterDuff.Mode.MULTIPLY 取两图层交集部分叠加后颜色。
16.PorterDuff.Mode.SCREEN 取两图层全部区域,交集部分变为透明色。

根据我们的效果需要,很明显选择:

[10.PorterDuff.Mode.SRC_ATOP ] 取下层非交集部分与上层交集部分。;

现在我只需要把SVG图片放下面,然后把妹子放上面,就能得到最终效果!

SVG跟妹子合并方法,也是我们最后在界面中使用的方法getSvgShapBitmap()

   /**
     * SVG跟妹子图片进行合并
     * @param context
     * @param fg 原图
     * @param resId 矢量图的(SVG)ID
     * @return Bitmap
     */
    public static Bitmap getSvgShapBitmap(Context context,Bitmap fg,int resId){
        //1.确定截取原图正方形的边长 (以原图中宽高最小的为边长)
        int size = Math.min(fg.getWidth(),fg.getHeight());
        //2.确定截取正方形左上角的坐标
        int x = (fg.getWidth()-size)/2;
        int y = (fg.getHeight()-size)/2;
        //裁剪妹子图片
        Bitmap girl = Bitmap.createBitmap(fg,x,y,size,size);

        //3.获得和正方形同样大小的SVG图片
        Bitmap svg = getSvgBitmap(context,fg.getWidth(),fg.getHeight(),resId);
        //创建画笔
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setDither(true);//防止抖动

        //4.SVG做底部图片,妹子放上面,采用SRC_ATOP模式重叠
        Bitmap bitmap = Bitmap.createBitmap(size,size, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(svg,new Matrix(),paint);
        //设置图片重合模式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        canvas.drawBitmap(girl,new Matrix(),paint);
        return bitmap;
    }

3.界面使用,直接显示到ImageView##

MainActivity中的代码:

    public class MainActivity extends AppCompatActivity {
    private  Bitmap bitmap;
    private ImageView ivImage;
    private Button btnImage;

    ////加载多边形SVG
    private static int[] resIds = new int[]{
            R.raw.ba,
            R.raw.fengye,
            R.raw.linxin,
            R.raw.liu,
            R.raw.meihua,
            R.raw.pingguo,
            R.raw.qi,
            R.raw.qizi,
            R.raw.tuzi,
            R.raw.wujiaoxing,
            R.raw.yezi,
    };
    
    int flag = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivImage = (ImageView) this.findViewById(R.id.iv_image);
        btnImage = (Button) this.findViewById(R.id.btn_image);
        
        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.girl);//
        //为了效果先显示原图
        ivImage.setImageBitmap(bitmap);
        
        btnImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                flag = flag % (resIds.length);
                //得到合并后的图片
                Bitmap svgShapBitmap = SvgBitmapUtils.getSvgShapBitmap(MainActivity.this, bitmap, resIds[flag]);
                ivImage.setImageBitmap(svgShapBitmap);
                flag++;
            }
        });
    }

代码简单,就不多说了,下面还是贴上XML代码吧

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:background="@color/colorAccent"
    tools:context="zhengliang.com.svg_polygon_frame.MainActivity">
    <ImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:scaleType="centerCrop"
        android:layout_centerInParent="true"
        android:id="@+id/iv_image"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:id="@+id/btn_image"
        android:background="#22FFFFFF"
        android:text="加载妹子"/>
</RelativeLayout>

大工告成,最后小提示(SVG图片的path路径尽量使用封闭路径,不然会出现奇葩效果!!)

印象丶亮仔###

svg-android.jar下载

源码下载

博客地址:http://blog.csdn.net/qq_23179075/article/details/53285852

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,433评论 25 707
  • 原文链接:https://github.com/opendigg/awesome-github-android-u...
    IM魂影阅读 32,900评论 6 472
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 陈爷爷高寿, 今年九十九岁了。可秋风刘起麒 陈爷爷老是感到心绞痛, 家人赶紧把他送迸了县医院. 主治医师牛医生说可...
    一路走来不会累阅读 463评论 0 1
  • 创造,也可以指舞蹈中跳错的那一步,石头上凿坏的那一凿子。动作的成功与否不是主要的。这种努力在你看来是徒劳无益,这是...
    Sunny飞镜阅读 170评论 0 0