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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Android开发中,我们可以使用触摸事件处理来实现图片拖拽缩放旋转操作。 首先,要实现拖拽功能,我们需要监听触摸事件,并在触摸事件的ACTION_MOVE中更新图片的位置。我们可以通过获取触摸点的坐标,然后根据图片的尺寸和移动的距离来计算新的位置,并将图片设置到新的位置上。 其次,要实现缩放功能,我们同样需要监听触摸事件。在触摸事件的ACTION_POINTER_DOWN和ACTION_MOVE中,我们可以获取到两个触摸点的坐标,并根据它们之间的距离来计算缩放比例。然后我们可以通过Matrix矩阵来设置图片缩放比例,并将新的Matrix应用到图片上。 最后,实现旋转功能也需要监听触摸事件。在触摸事件的ACTION_POINTER_DOWN和ACTION_MOVE中,我们可以获取到两个触摸点的坐标,并根据它们之间的角度差来计算旋转的角度。同样,我们可以通过Matrix矩阵来设置图片旋转角度,并将新的Matrix应用到图片上。 需要注意的是,为了能够拖拽缩放旋转图片,我们需要在布局文件中将图片包裹在一个可交互的控件中,如FrameLayout或ImageView。并且在Java代码中,我们需要实现View的触摸事件监听接口,并重写相应的方法来处理触摸事件。 - 以上所述是一种基本的实现方式,在实际开发中,还可以结合手势检测器(GestureDetector)等技术来简化操作和增加灵活性。同时,还要注意处理边界问题和多点触控的情况,以提供更好的用户体验。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值