Lagging drill in bitmap while touch in Image view - android

I am just creating an application in which I need to drill into the bitmap, I succeed for that also but bitmap drill is lagging as I touch image view. Any help on this is really appreciated...Thanks..
Here is Main File
public class MainActivity extends Activity{
int x, y;
Bitmap background,foreground;
ImageView iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.img);
background = BitmapFactory.decodeResource(getResources(), R.mipmap.mug_shot);
foreground = BitmapFactory.decodeResource(getResources(), R.mipmap.poster);
iv.setImageBitmap(combineTwoBitmaps(background, foreground));
iv.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View view, MotionEvent event)
{
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
x = (int) (event.getRawX()+100);
y = (int) (event.getY()+100);
System.out.println("X : "+ x +" Y : "+ y);
foreground = punchAHoleInABitmap(foreground);
iv.setImageBitmap(combineTwoBitmaps(background,foreground));
System.out.println("Hello this is Test2");
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
});
}
private Bitmap punchAHoleInABitmap(Bitmap foreground)
{
System.out.println("Hello this is Tesyt");
Bitmap bitmap = Bitmap.createBitmap(foreground.getWidth(), foreground.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
canvas.drawBitmap(foreground, 0, 0, paint);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
float radius = (float)(getScreenSize().x *.35);
float x1 = (float) ((x*.5) + (radius * .5));
float y1 = (float) ((y*.5) + (radius * .5));
System.out.println("X1 : "+ x1 +" Y1 : "+ y1);
canvas.drawCircle(x1, y1, 50, paint);
return bitmap;
}
private Bitmap combineTwoBitmaps(Bitmap background, Bitmap foreground) {
Bitmap combinedBitmap = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig());
Canvas canvas = new Canvas(combinedBitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(background, 0, 0, paint);
canvas.drawBitmap(foreground, 0, 0, paint);
return combinedBitmap;
}
private Point getScreenSize() {
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
}

ACTION_MOVE is called many times when users slide the screen. This means you will create quite amount of bitmaps in short time.
With GestureDetector you can detect exact one slide/swipe/fling.

Related

How crop bitmap of selected area on canvas?

I am making an application I am unable to one issue last 3 days doing google as much possible.I make a circle on canvas and want to crop image that part and show that image in zoom mode.My first step is like in screen here:-
in this I am selecting area.here is my code used by me for this.
private float x, y;
private boolean zooming = false;
private Paint mPaint;
private Matrix mmatrix;
private Shader mShader;
private Bitmap mBitmap;
private List<Point> mpoints;
private List<MyPoints> mpointlist;
private Path mpath;
private Canvas mcanvas;
private Bitmap mresult_bitmap, resultingImage,finalbitmap;
private Context mcontext;
private boolean bfirstpoint = false;
private Point mfirstpoint = null;
private Point mlastpoint = null;
public CircularZoomView(Context context) {
super(context);
mcontext = context;
mpath = new Path();
mpoints = new ArrayList<Point>();
setBackgroundResource(R.drawable.testing);
mPaint = new Paint();
mresult_bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.testing);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0));
mPaint.setStrokeWidth(5);
mPaint.setColor(Color.RED);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (zooming && resultingImage!=null) {
zooming = false;
ShowImage(resultingImage);
canvas.drawBitmap(resultingImage,mmatrix, null);
}
boolean first = true;
for (int i = 0; i < mpoints.size(); i += 2) {
Point point = mpoints.get(i);
if (first) {
first = false;
mpath.moveTo(point.x, point.y);
} else if (i < mpoints.size() - 1) {
Point next = mpoints.get(i + 1);
mpath.quadTo(point.x, point.y, next.x, next.y);
} else {
mlastpoint = mpoints.get(i);
mpath.lineTo(point.x, point.y);
}
}
canvas.drawPath(mpath, mPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
x = event.getX();
y = event.getY();
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
if (bfirstpoint) {
if (comparepoint(mfirstpoint, point)) {
mpoints.add(mfirstpoint);
addCircleFromPath(mpath);
} else {
mpoints.add(point);
}
} else {
mpoints.add(point);
}
if (!(bfirstpoint)) {
mfirstpoint = point;
bfirstpoint = true;
}
invalidate();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
zooming = false;
this.invalidate();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
zooming = true;
mlastpoint = point;
if (mpoints.size() > 12) {
if (!comparepoint(mfirstpoint, mlastpoint)) {
mpoints.add(mfirstpoint);
addCircleFromPath(mpath);
}
}
this.invalidate();
break;
default:
break;
}
return true;
}
public Bitmap getCroppedBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
void ShowImage(Bitmap mbitmap) {
Display display = ((MainActivity) mcontext).getWindowManager().getDefaultDisplay();
int screenWidth = display.getWidth();
float imageWidth = (float)mbitmap.getWidth();
float imageHeight = (float)mbitmap.getHeight();
float newHeight = imageHeight / (imageWidth / screenWidth);
float newWidth = screenWidth;
float scaleWidth = screenWidth / imageWidth;
float scaleHeight = newHeight / imageHeight;
SetImageMatrix(mbitmap,scaleWidth,scaleHeight);
}
void SetImageMatrix(Bitmap image,float scaleWidth, float scaleHeight) {
mmatrix = new Matrix();
mmatrix.setTranslate(40,40);
mmatrix.postScale(scaleWidth/2, scaleHeight/2);
/*image.setImageMatrix(mmatrix);
image.setScaleType(ScaleType.MATRIX);
image.invalidate();*/
}
private boolean comparepoint(Point first, Point current) {
int left_range_x = (int) (current.x - 3);
int left_range_y = (int) (current.y - 3);
int right_range_x = (int) (current.x + 3);
int right_range_y = (int) (current.y + 3);
if ((left_range_x < first.x && first.x < right_range_x)
&& (left_range_y < first.y && first.y < right_range_y)) {
if (mpoints.size() < 10) {
return false;
} else {
return true;
}
} else {
return false;
}
}
private void addCircleFromPath(Path path){
RectF bounds = new RectF();
path.computeBounds(bounds, true);
int width = (int) (bounds.right-bounds.left);
int height = (int) (bounds.bottom-bounds.top);
if(width<20 && height<20){
path.reset();
return;
}
int radius ;
if(width>=height)
radius = Math.round(((width/2)));
else radius = Math.round((int) ((height/2)));
/*CircleTagObject circle = new CircleTagObject((int)bounds.left+width/2, (int)bounds.top+height/2, radius, crossBitmap, tagBitmap,circleArray.size(),
ImageEditorView.this);
circleArray.add(circle);
tagBallID = circleArray.size() - 1;
dragEnable = true;*/
resultingImage = getCroppedBitmap(Bitmap.createBitmap(mresult_bitmap,0,0,200,200));
mcanvas = new Canvas(resultingImage);
path.reset();
resetView();
invalidate();
}
public void resetView() {
mpoints.clear();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0));
mPaint.setStrokeWidth(5);
mPaint.setColor(Color.RED);
invalidate();
}
If I create hard coded bitmap like above its showing good but not crop bitmap of selected part.Like this image.
but when add exact coordinate of selected area Like as:-
resultingImage = getCroppedBitmap(Bitmap.createBitmap(mresult_bitmap,(int)bounds.left,(int)bounds.top,width,height));
Then exception occure:-
07-12 10:58:56.700: E/MessageQueue-JNI(12310): java.lang.IllegalArgumentException: y + height must be <= bitmap.height()
07-12 10:58:56.700: E/MessageQueue-JNI(12310): at android.graphics.Bitmap.createBitmap(Bitmap.java:565)
07-12 10:58:56.700: E/MessageQueue-JNI(12310): at android.graphics.Bitmap.createBitmap(Bitmap.java:530)
07-12 10:58:56.700: E/MessageQueue-JNI(12310): at com.intel.view.CircularZoomView.addCircleFromPath(CircularZoomView.java:237)
I know why This exception occurs but unable to find solution how crop image of selected part.Thanks in advance.
I know its too late for your solution but this may help to others Use of this code
help you to come out from this problem.

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

Android graphics: Low performance

I'm making a custom slide control. Is like a Volume wheel, so some values augment or decrease depending on rotate direction.
I have two issues with this:
The performance is really low
The garbage collector is trigger, many many times.
Well, I'm sure that i'm doing something wrong, so please give me a Light.
Am working with Android graphics on 2.1 (eclaire) SDK.
This is the code of the view that am calling from my activity:
public class DrawingView extends View {
private Paint p;
Bitmap bitmap;
Context mContext;
Canvas canvas;
private float sweepAngle;
private int _height;
private int _width;
private float lastAngle;
private int percent;
public DrawingView(Context context) {
super(context);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
this.set_Width(display.getWidth());
this.set_Height(display.getHeight());
this.setSweepAngle(10);
mContext = context;
p = new Paint();
p.setAntiAlias(true);
}
protected int getAngleFromLocation(Point location){
int finalAngle = (int) (Math.atan2(location.y - 200, location.x - 200) * (180 / Math.PI));
return finalAngle;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),Bitmap.Config.ARGB_8888);
this.canvas = new Canvas(bitmap);
RectF rectF = new RectF();
rectF.set(20, 20, this.get_Widtt() - this.get_Widtt()/10, this.get_Widtt() - this.get_Widtt()/10);
canvas.drawArc(rectF, 180, this.getSweepAngle(), true, p);
//invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
double increment = 3.6;
Point touchLocation = new Point();
touchLocation.x = (int)event.getX();
touchLocation.y = (int)event.getY();
canvas.drawBitmap(bitmap = Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_8888),event.getX(), event.getY(),null );
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
lastAngle = this.getAngleFromLocation(touchLocation);
System.out.println("ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("ACTION_MOVE");
int currentAngle = this.getAngleFromLocation(touchLocation);
System.out.println("CURRENT ANGLE: " + currentAngle);
if (currentAngle > lastAngle || (currentAngle == 1 && lastAngle == 359)) {
percent += increment;
} else if (currentAngle < lastAngle) {
percent -= increment;
}
if (percent > 360) {
percent = 360;
} else if (percent < 0) {
percent = 0;
}
lastAngle = currentAngle;
this.setSweepAngle(percent);
//Write the label
//int realPercent = percent*100/360;
System.out.println("PERCENT: "+percent);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
No need to create a new bitmap on every frame. In fact you should try to avoid allocationg any objects at all in onDraw().
Try this:
private RectF mRectF = new RectF();
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
mRectF.set(20, 20, this.get_Widtt() - this.get_Widtt() / 10, this.get_Widtt() - this.get_Widtt() / 10);
canvas.drawArc(rectF, 180, this.getSweepAngle(), true, p);
}
also remove the call to canvas.drawBitmap() in onTouchEvent.
It's most likely the bitmap/canvas creation that's taking so long and triggering the GC so much. You want to do as little object creation as possible during onDraw() in particular, and onTouchEvent() as well. Is there any reason you can't move that to a separate method that gets called once and reuse the same bitmap each frame? It looks like the values you're passing to createBitmap() are static, so it shouldn't be an issue.

Combine two bitmap and save as jpg format in android?

i have two bitmap in my project what i need is that i need to combine those two bit map and combine those bit map to a single image i will show my code
public class FotosurpriseActivity extends Activity {
/** Called when the activity is first created. */
Bitmap overlay;
Paint pTouch;
int X = -100;
int Y = -100;
Canvas c2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.android);
Bitmap mBitmapover = BitmapFactory.decodeResource(getResources(), R.drawable.ss);
overlay = BitmapFactory.decodeResource(getResources(),R.drawable.ss).copy(Config.ARGB_8888, true);
c2 = new Canvas(overlay);
pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
// pTouch.setXfermode(new PorterDuffXfermode(Mode.TARGET);
pTouch.setColor(Color.TRANSPARENT);
pTouch.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL));
setContentView(new BitMapView(this, mBitmap,mBitmapover));
}
class BitMapView extends View {
Bitmap mBitmap = null;
Bitmap mBitmapover = null;
public BitMapView(Context context, Bitmap bm, Bitmap bmover) {
super(context);
mBitmap = bm;
mBitmapover = bmover;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_MOVE: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_UP:
break;
}
return true;
}
#Override
protected void onDraw(Canvas canvas) {
// called when view is drawn
Paint paint = new Paint();
paint.setFilterBitmap(true);
// The image will be scaled so it will fill the width, and the
// height will preserve the image’s aspect ration
/* double aspectRatio = ((double) mBitmap.getWidth()) / mBitmap.getHeight();
Rect dest = new Rect(0, 0, this.getWidth(),(int) (this.getHeight() / aspectRatio));
double aspectRatio2 = ((double) mBitmapover.getWidth()) / mBitmapover.getHeight();
Rect dest2 = new Rect(0, 0, this.getWidth(),(int) (this.getHeight() / aspectRatio2));
canvas.drawBitmap(mBitmap, null, dest, paint);
canvas.drawBitmap(mBitmapover, null, dest2, paint); */
//draw background
canvas.drawBitmap(mBitmap, 0, 0, null);
//copy the default overlay into temporary overlay and punch a hole in it
c2.drawBitmap(mBitmapover, 0, 0, null); //exclude this line to show all as you draw
c2.drawCircle(X, Y, 80, pTouch);
//draw the overlay over the background
canvas.drawBitmap(overlay, 0, 0, null);
}
}
}
how can i make this happen?
The onDraw function draws to the view. You don't actually need to do that at all. You can do this all in memory where the bitmaps reside. You draw the other bitmap on C2 as well. You don't have to draw anything to canvas in the onDraw() all that does is draw that to the screen.

Categories

Resources