最近需要做一个服装搭配的功能,总得来说就是对多张图片进行拖拽、缩放、旋转,找了一圈,找到了一个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;
}
效果图如下:
是否治好了你多年的颈椎病?