Issue
I need to produce the effect of drawing a bitmap in a circle shape, this circle will be growing from the center until it reaches the maximum radius, to do that I wrote the following method:
public Bitmap applyDrawingEffect(Bitmap src, int nRadiusprct)
{
// image size
int width = src.getWidth();
int height = src.getHeight();
// create bitmap output
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
// set canvas for painting
Canvas canvas = new Canvas(result);
canvas.drawARGB(0, 0, 0, 0);
// config paint
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
// config rectangle for embedding
final Rect rect = new Rect(0, 0, width, height);
final RectF rectF = new RectF(rect);
// draw rect to canvas
//canvas.drawRoundRect(rectF, round, round, paint);
float fRadius = (width<=height) ? (width/2) : (height/2);
canvas.drawCircle(width/2, height/2, (fRadius * nRadiusprct/100), paint);
// create Xfer mode
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// draw source image to canvas
canvas.drawBitmap(src, rect, rect, paint);
// return final image
return result;
}
As you see I passed the radius percentage as a parameter, my question is How I can optimize the code more and more, why do I need to create a bitmap everytime and assign it to a new canvas instance and repaint again....
Is there any way to create a single bitmap and draw over it many times to produce the same effect.
Solution
For the simple way to use a canvas and a bitmap, you can use it along with one of Androids animation methods to do the heavy lifting. Below I wrote a translate animation using the value animator to move my bitmap inside of the canvas. It doesn't require recreate the bitmap over and over again.
public void doCanvas(){
//Create our resources
Bitmap bitmap = Bitmap.createBitmap(mLittleChef.getWidth(), mLittleChef.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
final Bitmap chefBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.dish_special);
final Bitmap starBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.star);
//Link the canvas to our ImageView
mLittleChef.setImageBitmap(bitmap);
ValueAnimator animation= ValueAnimator.ofInt(canvas.getWidth(),0,canvas.getWidth());
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (Integer) animation.getAnimatedValue();
//Clear the canvas
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawBitmap(chefBitmap, 0, 0, null);
canvas.save();
canvas.translate(value,0);
canvas.drawBitmap(starBitmap, 0, 0, null);
canvas.restore();
//Need to manually call invalidate to redraw the view
mLittleChef.invalidate();
}
});
animation.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation) {
simpleLock= false;
}
});
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(mShortAnimationDuration);
animation.start();
}
For more about the code and canvas, and the different way to use canvas and bitmap see here
Answered By - Whitney
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.