I am using Image view and drawing overlay image using layerDrawable.
I have used two bitmaps original and myBitmap.
After zoom I am not able draw circle in correct location, it's drawn in different location.
This is the code I am using,
ImageView view = (ImageView) findViewById(R.id.imageView);
view.setOnTouchListener(this);
Options options = new BitmapFactory.Options();
options.inScaled = false;
original = BitmapFactory.decodeResource(getResources(), R.drawable.mainscreen,options);
original= getResizedBitmap(original, width, 200);
myBitmap = func(original);
Resources r = getResources();
layers = new Drawable[2];
layers[0] = new BitmapDrawable(original);
layers[1] = new BitmapDrawable(myBitmap);
LayerDrawable layerDrawable = new LayerDrawable(layers);
view.setImageDrawable(layerDrawable);
bitmap = Bitmap.createBitmap(width, 200, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap);
pcanvas.drawBitmap(grayScale, 0, 0, null);
public boolean onTouch(View v, MotionEvent rawEvent) {
WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
// ...
ImageView view = (ImageView) v;
// Dump touch event to log
// dumpEvent(event);
if (isZoomRequired == false)
{
x = (int) rawEvent.getX();
y = (int) rawEvent.getY();
r = SettingsActivity.brushsize;
pcanvas.drawCircle(x, y, r, mPaint);
layers[1] = new BitmapDrawable(bitmap);
LayerDrawable layerDrawable = new LayerDrawable(layers);
view.setImageDrawable(layerDrawable);
}
else
{
// 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; // indicate event was handled
}
Kindly help me. I need to draw circle in correct location after zoom.
Any help would be appreciated.
Could you add images showing what it is you're trying to get and a pic showing what you get instead?
One thing to keep in mind is that certain operations use a different zero point for the y axis. I've been fighting this on matrix operations on a surfaceview, where I've had to calculate a correction factor because one operation used the top of the view as y=0 and the matrix operation used the bottom of the view as y=0, so the actual matrix operation needed something like: matrixY = (totalHeightY - Yposition).
But showing what you expect and what you're getting would help diagnose the problem quicker than running and working through your code :)
I could see the matrix.preTranslate has not been used before you use postTranslate to make sure that view sets the image in correct place.
This is hard to answer correctly without knowing what you are trying to do.
I suggest that you create another class that extends View and use this to draw the circle on top of your ImageView in your activity. This also would allow you to draw as many circles (if you are planning on more than 1) without having to create some function inside your Activity.
Once you create your class that extends View, then on your onDraw() method you can draw the circle by canvas.drawCircle() and canvas.translate() to move it around the screen. You will have to use onTouchEvent and intercept the touch events for this.
There is a good example here with apk included: http://adblogcat.com/custom-view-to-draw-rotate-erase-and-convert-images-to-black-and-white/
As below OnTouchListener you can zoom your image or bitmap.when your zoom level is archived then
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
}
});
}
Now start to draw circle on zoom portion of image,here i write code for simple paint.You can put your code for draw circle in below listener.Hope this is useful for you.
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);
}
}