我使用canvas来缩放包含图像的绘制视图,包括使用setImageMatrix()。如下图所示类用于缩放和绘制线。但问题就出现了,那就是整个屏幕变得放大/缩小然后当我点击绘画按钮时我将一个布尔值传递为false,在手指触摸时绘制线条。但是在绘制线条之后在图像上我想要开始捏缩放这个绘图线,然后我也可以放大/缩小绘画颜色,但它没有以正确的方式改变油漆视图的xy。所以,如果有人知道这个问题,请回复plz。
public class PaintScreen extends Activity {
Context mContext;
private Paint mPaint;
MaskFilter mEmboss;
MaskFilter mBlur;
private LinearLayout mPaintBaseLayout;
private PaintView mPaintView;
// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
Matrix savedMatrix2 = new Matrix();
private int WIDTH = 0;
private int HEIGHT = 1;
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int POINT2 = 2;
static final int ZOOM = 3;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
float newDist;
float distanceOffset = 50f;
float minOffset = 50f;
float maxOffset = 10000f;
private boolean falg = true;
private int startval = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_main);
this.initialize();
this.PaintSet();
Button button = (Button) findViewById(R.id.btnzoom);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (falg) {
getFlag(false);
} else {
getFlag(true);
}
}
});
Button btnset = (Button) findViewById(R.id.btnset);
btnset.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startval = 1;
}
});
}
private void initialize() {
mPaintBaseLayout = (LinearLayout) findViewById(R.id.paint_paint_base_layout);
mContext = this;
mPaint = new Paint();
mPaintView = new PaintView(mContext);
mPaintView.setBackgroundColor(Color.TRANSPARENT);
mPaintBaseLayout.addView(mPaintView, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
mPaintBaseLayout.setBackgroundColor(Color.TRANSPARENT);
mPaintView.setScaleType(ScaleType.MATRIX);
mPaintView.setMPaint(mPaint);
Bitmap bm = BitmapFactory
.decodeResource(getResources(), R.drawable.nat);
mPaintView.setImageBitmap(bm);
mPaintView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
PaintView view = (PaintView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if (falg) {
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
} else {
view.onTouchEvent(event);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (falg) {
oldDist = spacing(event);
if (oldDist > 10f) {
start.set(event.getX(), event.getY());
savedMatrix.set(matrix);
midPoint(mid, event);
// mode = POINT2;
mode = ZOOM;
}
}
break;
case MotionEvent.ACTION_UP:
if (falg) {
mode = NONE;
distanceOffset = minOffset;
}
case MotionEvent.ACTION_POINTER_UP:
if (falg) {
mode = NONE;
distanceOffset = minOffset;
}
break;
case MotionEvent.ACTION_MOVE:
if (falg) {
if (mode == POINT2) {
newDist = spacing(event);
if (newDist - oldDist > 5f
|| newDist - oldDist < -5f) {
mode = ZOOM;
} else {
start.set(event.getX(), event.getY());
mode = DRAG;
}
} else if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x,
event.getY() - start.y);
} else if (mode == ZOOM) {
newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
} else {
view.onTouchEvent(event);
}
break;
}
// if (startval == 1) {
view.cMatrix(matrix);
// }
view.setImageMatrix(matrix);
matrixTurning(matrix, view);
return true;
}
});
}
public boolean getFlag(boolean b) {
return falg = b;
}
/** Determine the space between the first two fingers */
private static 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);
}
/** Calculate the mid point of the first two fingers */
private static 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);
}
private void matrixTurning(Matrix matrix, ImageView view) {
float[] value = new float[9];
matrix.getValues(value);
float[] savedValue = new float[9];
savedMatrix2.getValues(savedValue);
// view size
int width = view.getWidth();
int height = view.getHeight();
// image size
Drawable d = view.getDrawable();
if (d == null)
return;
int imageWidth = d.getIntrinsicWidth();
int imageHeight = d.getIntrinsicHeight();
int scaleWidth = (int) (imageWidth * value[0]);
int scaleHeight = (int) (imageHeight * value[0]);
if (value[2] < width - scaleWidth)
value[2] = width - scaleWidth;
if (value[5] < height - scaleHeight)
value[5] = height - scaleHeight;
if (value[2] > 0)
value[2] = 0;
if (value[5] > 0)
value[5] = 0;
if (value[0] > 10 || value[4] > 10) {
value[0] = savedValue[0];
value[4] = savedValue[4];
value[2] = savedValue[2];
value[5] = savedValue[5];
}
if (imageWidth > width || imageHeight > height) {
if (scaleWidth < width && scaleHeight < height) {
int target = WIDTH;
if (imageWidth < imageHeight)
target = HEIGHT;
if (target == WIDTH)
value[0] = value[4] = (float) width / imageWidth;
if (target == HEIGHT)
value[0] = value[4] = (float) height / imageHeight;
scaleWidth = (int) (imageWidth * value[0]);
scaleHeight = (int) (imageHeight * value[4]);
if (scaleWidth == width)
value[0] = value[4] = (float) width / imageWidth;
if (scaleHeight == height)
value[0] = value[4] = (float) height / imageHeight;
}
} else {
if (value[0] < 1)
value[0] = 1;
if (value[4] < 1)
value[4] = 1;
}
scaleWidth = (int) (imageWidth * value[0]);
scaleHeight = (int) (imageHeight * value[4]);
if (scaleWidth < width) {
value[2] = (float) width / 2 - (float) scaleWidth / 2;
}
if (scaleHeight < height) {
value[5] = (float) height / 2 - (float) scaleHeight / 2;
}
matrix.setValues(value);
savedMatrix2.set(matrix);
}
public void PaintSet() {
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(10);
// getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(24, BlurMaskFilter.Blur.NORMAL);
}
public void colorChanged(int color) {
mPaint.setColor(color);
}
}
class PaintView extends ImageView {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
// onDraw
private Paint mPaint;
// onTouch
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
public PaintView(Context context) {
this(context, null);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawColor(0xFFAAAAAA);
super.onDraw(canvas);
mCanvas = canvas;
// canvas = mCanvas;
Matrix localMatrix = new Matrix();
localMatrix.setRectToRect(
new RectF(0.0F, 0.0F, mBitmap.getWidth(), mBitmap
.getHeight()),
new RectF(0.0F, 0.0F, this.mCanvas.getWidth(),
this.mCanvas.getHeight()),
Matrix.ScaleToFit.CENTER);
canvas.drawBitmap(mBitmap, localMatrix, mBitmapPaint);
// canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
// canvas.drawBitmap(mBitmap, PaintScreen.matrix, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
public void setMPaint(Paint paint) {
mPaint = paint;
}
private void touchStart(float x, float y) {
// mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touchMove(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touchUp() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
Log.d("PaintView", "ev ->" + event.getAction());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
invalidate();
break;
}
return true;
}
public void cMatrix(Matrix matrix) {
mCanvas.setMatrix(matrix);
}
}
答案 0 :(得分:0)
尝试这样的事情,但我不确定
@Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub ImageView view = (ImageView) v; dumpEvent(event); // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG"); mode = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; Log.d(TAG, "mode=ZOOM"); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float newDist = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break; } view.setImageMatrix(matrix); return true; } 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()); } /** Determine the space between the first two fingers */ 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); } /** Calculate the mid point of the first two fingers */ 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); }
并且不要忘记将setscaleType属性设置为imageview标签的矩阵,如
<ImageView android:id="@+id/imageEnhance" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginBottom="15dp" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_marginTop="15dp" android:background="@drawable/enhanceimageframe" android:scaleType="matrix" > </ImageView>
,使用的变量是,
// 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; String savedItemClicked;
答案 1 :(得分:0)
带捏缩放和图像上的绘画的图像
imageView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix1);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
start.set(event.getX(), event.getY());
savedMatrix.set(matrix1);
midPoint(mid, event);
// mode = POINT2;
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
distanceOffset = minOffset;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
distanceOffset = minOffset;
break;
case MotionEvent.ACTION_MOVE:
if (mode == POINT2) {
newDist = spacing(event);
if (newDist - oldDist > 5f
|| newDist - oldDist < -5f) {
mode = ZOOM;
} else {
start.set(event.getX(), event.getY());
mode = DRAG;
}
} else if (mode == DRAG) {
matrix1.set(savedMatrix);
matrix1.postTranslate(event.getX() - start.x,
event.getY() - start.y);
} else if (mode == ZOOM) {
newDist = spacing(event);
if (newDist > 10f) {
matrix1.set(savedMatrix);
float scale = newDist / oldDist;
matrix1.postScale(scale, scale, mid.x,
mid.y);
finalscale = scale;
}
}
break;
}
view.setImageMatrix(matrix1);
// matrixTurning(matrix1, view);
return true; // indicate event was handled
}
});
}
mPaintView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
PaintView view = (PaintView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if (falg) {
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
} else {
view.onTouchEvent(event);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (falg) {
oldDist = spacing(event);
if (oldDist > 10f) {
start.set(event.getX(), event.getY());
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
}
break;
case MotionEvent.ACTION_UP:
if (falg) {
mode = NONE;
distanceOffset = minOffset;
}
case MotionEvent.ACTION_POINTER_UP:
if (falg) {
mode = NONE;
distanceOffset = minOffset;
}
break;
case MotionEvent.ACTION_MOVE:
if (falg) {
if (mode == POINT2) {
newDist = spacing(event);
if (newDist - oldDist > 5f
|| newDist - oldDist < -5f) {
mode = ZOOM;
} else {
start.set(event.getX(), event.getY());
mode = DRAG;
}
} else if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x,
event.getY() - start.y);
} else if (mode == ZOOM) {
newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
finalscale = scale;
}
}
} else {
view.onTouchEvent(event);
}
break;
}
limitZoom(matrix);
view.setImageMatrix(matrix);
matrixTurning(matrix, view);
RectF r = new RectF();
matrix.mapRect(r);
scaledImageOffsetX = r.left;
scaledImageOffsetY = r.top;
return true;
}
});
}
private void limitZoom(Matrix m) {
float[] values = new float[9];
m.getValues(values);
float scaleX = values[Matrix.MSCALE_X];
float scaleY = values[Matrix.MSCALE_Y];
if(scaleX > MAX_ZOOM) {
scaleX = MAX_ZOOM;
} else if(scaleX < MIN_ZOOM) {
scaleX = MIN_ZOOM;
}
if(scaleY > MAX_ZOOM) {
scaleY = MAX_ZOOM;
} else if(scaleY < MIN_ZOOM) {
scaleY = MIN_ZOOM;
}
values[Matrix.MSCALE_X] = scaleX;
values[Matrix.MSCALE_Y] = scaleY;
m.setValues(values);
}
public boolean getFlag(boolean b) {
return falg = b;
}
<强> PaintView.class 强>
class PaintView extends ImageView {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
// onDraw
private Paint mPaint;
// onTouch
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
public PaintView(Context context) {
this(context, null);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawColor(0xFFAAAAAA);
super.onDraw(canvas);
mCanvas = canvas;
// canvas = mCanvas;
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
// canvas.drawBitmap(mBitmap, PaintScreen.matrix, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
public void clear() {
mPaint.reset();
// invalidate();
}
public void setMPaint(Paint paint) {
mPaint = paint;
}
private void touchStart(float x, float y) {
// mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touchMove(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touchUp() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
Log.d("PaintView", "ev ->" + event.getAction());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
invalidate();
break;
}
return true;
}
public void cMatrix(Matrix matrix) {
mCanvas.setMatrix(matrix);
}
}