draw on pinch zoom canvas android
I am making an application in android in which, I want to draw on pinch zoom image on canvas and when i zoom out it should not distort.
I have to use both fingers in opposite and same direction for zoom in/out using pinch zoom and write on that zoom part without blurring the canvas.
This is my code for pinch zoom of image , now i want to draw using single finger on that view.
I am stuck at drawing on the view. this is code:
package com.pericent;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
public class Touch extends Activity implements OnTouchListener {
private static final String TAG = "Touch";
private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 8.0f;
// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
ImageView view;
Canvas canvas;
Path path;
Paint paint;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
MotionEvent event;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
view = (ImageView) findViewById(R.id.imageView);
//view.setLayoutParams(new GridView.LayoutParams(85, 85));
view.setScaleType(ImageView.ScaleType.FIT_CENTER);
view.setOnTouchListener(this);
float width = view.getMeasuredWidth();
float height = view.getMeasuredHeight();
Log.v(TAG,"---width:"+width+"---height:"+height);
onDraw();
}
public void myDrawLine(float x,float y){
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLUE);
paint.setAlpha(100);
// paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
// paint.setColor(0xFFFF0000);
paint.setStyle(Paint.Style.STROKE);
// paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(1);
canvas.drawLine(0, 0, x, y, paint);
Log.v(TAG,"---in myDrawLine() method---");
// view.draw(canvas);
//view.in
}
/**
float[] values = new float[9];
matrix.mapRadius(1);
matrix.getValues(values);
globalX = values[2];
globalY = values[5];
width = values[0]*imageWidth;
height = values[4]*imageHeight;
*/
//@Override
public void onDraw() {
Bitmap bitmap = Bitmap.createBitmap(600,900, Bitmap.Config.ARGB_8888);
bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.map).copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(bitmap);
path = new Path();
view.setImageBitmap(bitmap);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLUE);
paint.setAlpha(100);
canvas.drawBitmap(bitmap, 0, 0, paint);
// canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.drawPath(path, paint);
//canvas.drawRect(0, 0, 100, 100, paint); // transparent black on image
// view.draw(canvas);
Log.d(TAG, "---inside onDraw() method---");
}
public boolean onTouch(View v, MotionEvent event) {
float x = event.getX();
float y = event.getY();
float scale;
view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
// Dump touch event to log
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
//for drawing
// touch_start(x, y);
// invalidate();
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG" );
Log.v(TAG,"MotionEvent.ACTION_DOWN: //first finger down only");
mode = DRAG;
break;
case MotionEvent.ACTION_UP: //first finger lifted
// touch_up();
// invalidate();
case MotionEvent.ACTION_POINTER_UP: //second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE" );
Log.v(TAG,"MotionEvent.ACTION_POINTER_UP: //second finger lifted");
break;
case MotionEvent.ACTION_POINTER_DOWN: //second finger down
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
Log.v(TAG,"MotionEvent.ACTION_POINTER_DOWN: //second finger down");
if (oldDist > 5f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM" );
}
break;
case MotionEvent.ACTION_MOVE:
// touch_move(x, y);
// invalidate();
if (mode == DRAG) { //movement of first finger
matrix.set(savedMatrix);
// if (view.getLeft() >= -392){
Log.v("in DrG", "DRAWING POINT AT X="+event.getX()+" Y="+event.getY());
myDrawLine(event.getX(),event.getY());
//matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
// }
}
else if (mode == ZOOM) { //pinch zooming
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 5f) {
matrix.set(savedMatrix);
scale = newDist / oldDist; //thinking i need to play around with this value to limit it**
matrix.postScale(scale, s开发者_C百科cale, mid.x, mid.y);
}
}
break;
}
// Perform the transformation
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
private void touch_start(float x, float y) {
// path.reset();
path.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
path.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
private void touch_up() {
path.lineTo(mX, mY);
// commit the path to our offscreen
canvas.drawPath(path, paint);
// kill this so we don't double draw
path.reset();
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
/** Show an event in the LogCat view, for debugging */
private void dumpEvent(MotionEvent event) {
String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
"POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_" ).append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid " ).append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")" );
}
sb.append("[" );
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#" ).append(i);
sb.append("(pid " ).append(event.getPointerId(i));
sb.append(")=" ).append((int) event.getX(i));
sb.append("," ).append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";" );
}
sb.append("]" );
Log.d(TAG, sb.toString());
}
}
This is my xml code:
<ImageView android:id="@+id/imageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/map"
android:scaleType="matrix" >
</ImageView>
</FrameLayout>
Please help me for this as soon as possible. Thank you in advance.
You'd better use gesture recogniser lib instead of writing one yourself.
And furthermore, there's a library, namely TouchImageView, to handle touch pinch zoom on ImageView
You can find it here
精彩评论