Android 多点触控,多张图片拖拽,缩放,旋转

最近需要做一个服装搭配的功能,总得来说就是对多张图片进行拖拽、缩放、旋转,找了一圈,找到了一个demo: http://download.csdn.net/download/aomandeshangxiao/4189910
但是这个demo只支持单张图片,尝试添加两张图片,弄了一天,也无法解决焦点问题,所以只能尝试在canvas上自己画了(手势事件还是复制自此demo)。
对bitmap进行操作,就有一些额外的属性需要绑定到这个bitmap,中间点、缩放大小、旋转角度等,因为bitmap是final,不能被继承,所以新建了一个CustomBitmap:

public class CustomBitmap {
        
        private int id;//唯一标识,实际项目中可替换为url
        public float startDis;// 开始距离
        public PointF midPoint;// 中间点
        public float oldRotation = 0;
        public float rotation = 0;
        public PointF startPoint = new PointF();
        public Matrix matrix = new Matrix();
        public Bitmap bitmap;
        
        public CustomBitmap(Bitmap bitmap) {
                this.bitmap = bitmap;
        }
        
        public Bitmap getBitmap() {
                return bitmap;
        }

        public int getId() {
                return id;
        }

        public void setId(int id) {
                this.id = id;
        }

        public void setMatrix(Matrix matrix) {
                this.matrix = matrix;
        }
}

新建一个DrawingView继承View,把bitmap画在view上:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        //栈底的图显示在上面
        for(CustomBitmap bitmap:_bitmaps){
            canvas.drawBitmap(bitmap.getBitmap(), bitmap.matrix, paint);
        }
    }

在DOWN时间里面判断手指点击在哪个bitmap上面,让后把该bitmap放到数据栈的栈底,这样该bitmap始终在最上层

boolean isChanged = false;//当前操作bitmap是否改变
                for(CustomBitmap bitmap:_bitmaps){
                    float[] values = new float[9];
                    bitmap.matrix.getValues(values);
                    float globalX = values[Matrix.MTRANS_X];
                    float globalY = values[Matrix.MTRANS_Y];
                    float width = values[Matrix.MSCALE_X]*bitmap.getBitmap().getWidth();
                    float height = values[Matrix.MSCALE_Y]*bitmap.getBitmap().getWidth();
                    Log.e("tag", "globalX: " + globalX + " ,globalY: " + globalY + " ,t: " + width + " ,b: " + height);

                    Rect rect = new Rect((int)globalX, (int)globalY, (int)(globalX+width), (int)(globalY+height));
                    Log.e("tag", "l: " + rect.left + " ,r: " + rect.right + " ,t: " + rect.top + " ,b: " + rect.bottom);
                    if(rect.contains((int)event.getX(), (int)event.getY())){
                        _curCustomBitmap = bitmap;
                        isChanged = true;
                    }
                }
                //切换操作对象,只要把这个对象添加到栈底就行
                if(isChanged){
                    _bitmaps.remove(_curCustomBitmap);
                    _bitmaps.add(_curCustomBitmap);
                }

其他手势代码复制自上面提到的demo里面,就不贴了。这里讲讲怎样保存操作后的图像。
对bitmap的所有变换操作都可以通过matrix获得,获取matrix信息:

        Matrix matrix = customBitmap.matrix;
        float[] values = new float[9];
        matrix.getValues(values);

数组中各对应信息:

    //Matrix.MSKEW_X 控制X坐标的线性倾斜系数
    //Matrix.MSKEW_Y 控制Y坐标的线性倾斜系数
    //Matrix.MTRANS_X//左上顶点X坐标
    //Matrix.MTRANS_Y//左上顶点Y坐标
    //Matrix.MSCALE_X//宽度缩放倍数
    //Matrix.MSCALE_Y//高度缩放位数

所以我们只要保存这个float数组就可以了。保存和读取的代码如下:

    //保存matrix
    private void saveMatrix(CustomBitmap customBitmap){
        Log.e("tag", "save matrix" + customBitmap.getId());
        SharedPreferences.Editor editor = getSharedPreferences("matrix", 1).edit();
        Matrix matrix = customBitmap.matrix;
        float[] values = new float[9];
        matrix.getValues(values);
        JSONArray array = new JSONArray();
        for (float value:values){
            try {
                array.put(value);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        editor.putString(String.valueOf(customBitmap.getId()), array.toString());
        editor.commit();
    }

    //获取matrix
    private Matrix getSavedMatrix(int id){
        SharedPreferences sp = getSharedPreferences("matrix", 1);
        String result = sp.getString(String.valueOf(id), null);
        if (result != null){
            float[] values = new float[9];
            Matrix matrix = new Matrix();
                try {
                    JSONArray array = new JSONArray(result);
                    for (int i = 0; i < array.length(); i++) {
                        values[i] = Float.valueOf(String.valueOf(array.getDouble(i)));
                    }
                    matrix.setValues(values);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            return matrix ;
        }
        return null;
    }

效果图如下:


这里写图片描述

是否治好了你多年的颈椎病?

代码下载:
http://download.csdn.net/detail/pkxutao/8745023

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

推荐阅读更多精彩内容