Unable to draw on a mutable image android - android

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);

Related

Android draw on zoomed image

I'm trying to draw some points on an ImageView which also features DRAG and ZOOM capabilities.
My implementation works fine if the image is not modified ( zoomed or dragged ), but if I apply these types of transformations, it won't draw correctly anymore.
Instead it will hold the initial frame as reference and will draw the dots as if it weren't modified.
This is what the image looks like right after choosing it from the gallery and drawing a green dot by tapping on it.
This is what the image looks like after zooming it in and dragging it to the side. As you can see, if I tap inside the initial frame, it will draw the dot inside the image as if it were unscaled.
Bellow is the code (select image from gallery, onTouch method and the actual drawing).
public void onClick(View v) {
if (v.getId()==R.id.putPoint){
drawPath=true;
}
else
if (v == choosePicture) {
Intent choosePictureIntent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(choosePictureIntent, 0);
}
}
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK) {
Uri imageFileUri = intent.getData();
try {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
.getHeight(), bmp.getConfig());
canvas = new Canvas(alteredBitmap);
paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(5);
matrix = new Matrix();
canvas.drawBitmap(bmp, matrix, paint);
choosenImageView.setImageBitmap(alteredBitmap);
choosenImageView.setOnTouchListener(this);
} catch (Exception e) {
Log.v("ERROR", e.toString());
}
}
}
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
ImageView view = (ImageView) v;
if(drawPath) {
//I use this flag to enable drawing mode
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = event.getX();
downy = event.getY();
canvas.drawCircle(downx, downy, radius,paint);
choosenImageView.invalidate();
drawPath=false;
break;
}
return true;
}
else{
//if the drawing mode is not enable I can zoom and drag the image
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
lastEvent = null;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
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_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
lastEvent = null;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
matrix.postTranslate(dx, dy);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = (newDist / oldDist);
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
}
}
My goal is to be able to tap on the image(zommed or dragged) and see the points drawn correctly.
See: How do I get touch coordinates with respect to canvas after scaling and translating?
The easiest and most consistent way to do this is to apply the inverse matrix you used to modify the view modify the MotionEvent. There's two commands you need to know:
event.transform(invertMatrix);
and:
invertMatrix = new Matrix(viewMatrix);
invertMatrix.invert(invertMatrix);
Basically you do the opposite of what you did to the view to the touches. So the touches go to the scene space.

How to map the touch x, y to my canvas

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;

How to undo erasing when erase a bitmap on canvas?

I am working a project in which an erasing functionality is there I want to user can undo
his erasing if he want but this functionality is not working for me.
My code is as:-
public EraserView(Context context) {
super(context);
setFocusable(true);
setBackgroundResource(R.drawable.back);
// setting paint
mPaint = new Paint();
mPath = new Path();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setColor(Color.TRANSPARENT);
mPaint.setAntiAlias(true);
// getting image from resources
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.drawable.image2);
// converting image bitmap into mutable bitmap
bitmap = bm.createBitmap(295, 260, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
pcanvas.drawBitmap(bm, 0, 0, null);
paths.add(mPath);
}
#Override
protected void onDraw(Canvas canvas) {
// draw a circle that is erasing bitmap
pcanvas.drawCircle(x,y,r,mPaint);
/*for (Path objpath : paths) {
pcanvas.drawPath(objpath, mPaint);
}*/
canvas.drawBitmap(bitmap, 0, 0, null);
setBitmap(bitmap);
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
case MotionEvent.ACTION_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
case MotionEvent.ACTION_MOVE:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
case MotionEvent.ACTION_POINTER_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
}
return true;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
public void onClickUndo () {
if (paths.size()>0)
{
paths.add(paths.remove(paths.size()-1));
invalidate();
}
else
{
}
}![enter image description here][1]
as shown in image we erase some part of dog after that click undo button dog should come in his initial position.please any one guide me.
Have you tried saving (Canvas.save()) the Canvas before erasing any portion of the bitmap and then restoring (Canvas.restore()) and redrawing once the button is clicked?

How to save canvas overlay bitmap in sd-card?

I am making an app in which I am drawing a bitmap on a canvas as a overlay after erasing some part of overlay bitmap I want to save it into sd-card but when is save it contain black
UI like attach screen
And My code is bellow:-
public EraserView(Context context) {
super(context);
setFocusable(true);
setBackgroundResource(R.drawable.back);
// setting paint
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setColor(Color.TRANSPARENT);
mPaint.setAntiAlias(true);
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.drawable.image2);
bitmap = bm.createBitmap(295, 260, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
pcanvas.drawBitmap(bm, 0, 0, null);
}
#Override
protected void onDraw(Canvas canvas) {
pcanvas.drawCircle(x, y, r, mPaint);
canvas.drawBitmap(bitmap, 0, 0, null);
setBitmap(bitmap);
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
r = 2;
invalidate();
break;
case MotionEvent.ACTION_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 20;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
x = (int) event.getX();
y = (int) event.getY();
r =2;
invalidate();
break;
case MotionEvent.ACTION_POINTER_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 2;
// Atlast invalidate canvas
invalidate();
break;
}
return true;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
But My requirement is only save overlay thanks in advance.
When CompressFormat is JPEG its shows you black background because JPEG format does not support alpha transparency, just change CompressFormat to PNG and even save your image in png format instead jpeg. check below code:
ByteArrayOutputStream objbytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, objbytes);
While delcare path of image, use .png extension.
directory + "/pics+"+System.currentTimeMillis()+".png";

How to draw a line using ontouchevent in image Bitmap as a background in android

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..

Categories

Resources