I have a task to build image editor and to be able to draw on my image
attached is my example
the problem now that when I try to draw the drawing line is shifted, and also when I try to draw outside of my image, it draw also, so how can I solve this problem
my code is as following :
float touchX = event.getX();
float touchY = event.getY();
Log.i("AMIRA" , "X: " + touchX + " Y: " +touchY);
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
canvasBitmap = ((FastBitmapDrawable) getDrawable()).getBitmap();
mutableBitmap = canvasBitmap.copy(Bitmap.Config.ARGB_8888, true);
drawCanvas = new Canvas(mutableBitmap);
float x1= touchX - drawCanvas.getClipBounds().left;
float y1= touchY - drawCanvas.getClipBounds().top;
//drawPath.lineTo(touchX, touchY);
drawPath.lineTo(x1, y1);
drawCanvas.drawPath(drawPath, drawPaint);
setImageBitmap(mutableBitmap);
break;
case MotionEvent.ACTION_UP:
canvasBitmap = ((FastBitmapDrawable) getDrawable()).getBitmap();
mutableBitmap = canvasBitmap.copy(Bitmap.Config.ARGB_8888, true);
drawCanvas = new Canvas(mutableBitmap);
float x2= touchX - drawCanvas.getClipBounds().left;
float y2= touchY - drawCanvas.getClipBounds().top;
//drawPath.lineTo(touchX, touchY);
drawPath.lineTo(x2, y2);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
setImageBitmap(mutableBitmap);
break;
default:
return false;
}
invalidate();
return true;
Related
I want to get current x, y coordinates when i scale and translate canvas, how can i achieve this?
When canvas scale and Translate after not get current x y position and i get different x,y coordinate.
Below is My Canvas code
canvas.save();
super.onDraw(canvas);
canvas.setMatrix(getImageMatrix());
matrix1.set(getImageMatrix());
tempscalx = getscalx();
tempscaly = getscaly();
this.f1658w[0] = 0.0f;
this.f1658w[1] = 0.0f;
this.f1658w[2] = (float) getWidth();
this.f1658w[3] = (float) getHeight();
getImageMatrix().mapPoints(this.f1658w);
drawCanvas.drawColor(65536, PorterDuff.Mode.CLEAR);
if (replaceboolean_for_shape) {
drawCanvas.drawBitmap(original, 0, 0, null);
drawCanvas.drawBitmap(framebt, matrix, null);
drawCanvas.drawBitmap(maskbt, matrix, maskpaint);
canvas.drawBitmap(black, 0.0f, 0.0f, null);
} else {
drawCanvas.drawBitmap(black, 0, 0, null);
drawCanvas.drawBitmap(framebt, matrix, null);
drawCanvas.drawBitmap(maskbt, matrix, maskpaint);
canvas.drawBitmap(original, 0.0f, 0.0f, null);
}
canvas.drawBitmap(canvasBitmap, 0.0f, 0.0f, null);
this.setDrawingCacheEnabled(true);
color_priview_bitmap = this.getDrawingCache(true);
canvas.restore();
and Below is my OnTouchEvent() code.
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
savedMatrix.set(matrix);
**//Here in below Line i cant get proper [getX & getY]**
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_UP: //second finger lifted
mode = NONE;
lastEvent = null;
break;
case MotionEvent.ACTION_POINTER_DOWN: //second finger down
oldDist = spacing(event);
if (oldDist > 5f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = event.getX(0);
lastEvent[1] = event.getX(1);
lastEvent[2] = event.getY(0);
lastEvent[3] = event.getY(1);
d = rotation(event);
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) { //movement of first finger
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
if (lastEvent != null) {
newRot = rotation(event);
float r = newRot - d;
matrix.postRotate(r, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
}
}
break;
}
Use this method to get co-ordinates on canvas touch point
final float[] getPointerCoords(ImageView view, MotionEvent e){
final int index = e.getActionIndex();
final float[] coords = new float[] { e.getX(index), e.getY(index) };
Matrix matrix = new Matrix();
view.getImageMatrix().invert(matrix);
matrix.postTranslate(view.getScrollX(), view.getScrollY());
matrix.mapPoints(coords);
return coords;
}
i am working on a paint application and i want to draw a path of bitmap
my code is this:
private void onCanvasInitialization() {
// Main_Activity.paintButton.setEnabled(true);
mPaint = new Paint();
BlurMaskFilter bmf = new BlurMaskFilter(2, Blur.OUTER);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setFilterBitmap(true);
mPaint.setColor(Main_Activity.colorchanger);
mCanvas = new Canvas();
mPath = new Path();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setMaskFilter(bmf);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setAlpha(255);
bmp = Bitmap.createScaledBitmap(bmp, 30, 30, false);
bmp = bmp.copy(Config.ARGB_8888, true);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (true)
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
private void touch_start(float x, float y) {
Random rand = new Random();
float r = rand.nextFloat();
float g = rand.nextFloat();
float b = rand.nextFloat();
Random rnd = new Random();
mPaint.setColor(Color.rgb(rnd.nextInt(256), rnd.nextInt(256),
rnd.nextInt(256)));
mPath.reset();
mPath.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) {
// mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
arrX[i] = mX;
arrY[i] = mY;
i++;
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int k = 0; k < i; k++) {
canvas.drawBitmap(bmp, arrX[k], arrY[k], mPaint);
}
}
by this i am able to draw bitmap on canvas but the flow is not smooth it is not looks like a line .there is a gap between the two successive bitmaps.i want it to look like a path .
Why are you calling invalidate() method in every case: , try to call it out ot switch.
For Ex.
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (true)
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
break;
case MotionEvent.ACTION_UP:
touch_up();
break;
}
invalidate();
return true;
}
I am trying to draw lines on an image i am loading from my internal memory using the below mentioned code but it is not working
imgView = (ImageView) findViewById(R.id.imageView);
bitmap = BitmapFactory.decodeFile(img1.getAbsolutePath()).copy(Bitmap.Config.ARGB_8888,true);
canvas = new Canvas(bitmap);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
imgView.setImageBitmap(bitmap);
imgView.setOnTouchListener(this);
but when i change the code to :
imgView = (ImageView) findViewById(R.id.imageView);
bitmap = Bitmap.createBitmap((int) dw, (int) dh, Bitmap.Config.ARGB_8888);;
canvas = new Canvas(bitmap);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
imgView.setImageBitmap(bitmap);
imgView.setOnTouchListener(this);
i am able to draw the lines with my finger
Any suggestions ?
OnTouchCodeListner Function
public boolean onTouch(View v, MotionEvent event){
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = event.getX();
downy = event.getY();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
upx = event.getX();
upy = event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
imgView.invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
This is probably because it fails to make it mutable. Try using
Bitmap.createBitmap(BitmapFactory.decodeFile(img1.getAbsolutePath()),dw,dh);
Below is a switch case logic for drawing on the surface, it doesn't draw properly. Not sure where am i going wrong. EDIT: class was removed as it was not helpful.
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (mThread.getSurfaceHolder()) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_DOWN:
currentDrawingPath = null;
currentDrawingPath = new DrawingPath();
currentDrawingPath.getPath().moveTo(eventX, eventY);
startX = eventX;
startY = eventY;
canvasPaths.add(currentDrawingPath);
//invalidate();
break;
case MotionEvent.ACTION_MOVE:
float dx = Math.abs(eventX - startX);
float dy = Math.abs(eventY - startY);
currentDrawingPath.getPath().quadTo(startX, startY,
(eventX + startX)/2, (eventY + startY)/2);
startX = eventX;
startY = eventY;
//currentDrawingPath.getPath().lineTo(startX, startY);
break;
}
return true;
Following is the code that fixed the issue,
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
currentDrawingPath.getPath().lineTo(event.getX(), event.getY());
break;
case MotionEvent.ACTION_DOWN:
currentDrawingPath = new DrawingPath();
currentDrawingPath.setPaintForPath();
// update the starting point of the new path
currentDrawingPath.getPath().moveTo(event.getX(), event.getY());
currentDrawingPath.getPath().lineTo(event.getX(), event.getY());
canvasPaths.add(currentDrawingPath);
break;
case MotionEvent.ACTION_MOVE:
currentDrawingPath.getPath().lineTo(event.getX(), event.getY());
break;
}
return true;
How to draw a line using ontouchevent in image Bitmap as a background in android.here i am using image Bitmap as a background image in android.But the image will not be Overlapped if i draw a line.
this is a beautiful link, u can follow this for your solution:
How to draw a line in android
use something like this in your on touch
/////declare variable/////
float downx = 0;
float downy = 0;
float upx = 0;
float upy = 0;
Canvas canvas;
Paint paint;
///////put this in on create//////
imageView = (ImageView)findViewById(R.id.ImageView);
bitmap = Bitmap.createBitmap(480,640,Bitmap.Config.ARGB_8888);
Display currentDisplay = getWindowManager().getDefaultDisplay();
float dw = currentDisplay.getWidth();
float dh = currentDisplay.getHeight();
canvas = new Canvas(bitmap);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStrokeWidth(6);
paint.setStrokeMiter(2);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
imageView.setImageBitmap(bitmap);
imageView.setOnTouchListener(this);
/////bitmap = your bitmap you want to load as back ground/////
/////your on touch method///////
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
downx = event.getX();
downy = event.getY();
break;
case MotionEvent.ACTION_MOVE:
upx = event.getX();
upy = event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
imageView.invalidate();
downx = upx;
downy = upy;
break;
case MotionEvent.ACTION_UP:
upx = event.getX();
upy = event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
imageView.invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
i hope you got your answer..