Friday, March 9, 2012

Create Semi Transparent Rounded Border Image in Android

Hey, I am back.

In the earlier post, if you do notice that I wrote that I'm about to enter new chapter of life. It's been months and you are still waiting to know what I've been up to. I promised, it's coming pretty soon. In about a month time. :) 

Lots of things happened these days, lots of things not sorted out, and I've to work it out one after another all in a short time span. Life is pretty busy. 

Anyway, this Android passion drives my adrenaline. Here comes another Android stuff.

The tutorial is derived from Eric Burke's talk: Taming Android UIs with Eric Burke of Square I won't focus on the entire talk.

The only stuff I will focus is creating the semi transparent rounded border image in Android. Actually half of the codes is available in the talk itself. I just tried to complete/translate what he is presenting into a set of runnable codes.



Create Rounded Image

Drawable imageDrawable = (image != null) ? new BitmapDrawable(image) : placeHolder; Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); RectF outerRect = new RectF(0, 0, size, size); float cornerRadius = size / 10f; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); canvas.drawRoundRect(outerRect, cornerRadius, cornerRadius, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); imageDrawable.setBounds(0, 0, size, size); // Save the layer to apply the paint canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG); imageDrawable.draw(canvas); canvas.restore();
The above code will produce the following image, nice rounded corner


Create Frame

There are several steps in creating frame. The same principle is used here in composing the image (creating frame).
  1. Create offscreen bitmap Go direct to YouTube screen 
  2. Draw an opaque rounded rectangle Go direct to YouTube screen  
  3. Set the Power Duff mode  Go direct to YouTube screen  
  4. Draw a translucent rounded rectangle Go direct to YouTube screen  


Step 1. Create offscreen bitmap

// 1. Create offscreen bitmap link: http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1035s Bitmap framedOutput = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas framedCanvas = new Canvas(framedOutput); // End of Step 1 // Start Dummy Step - TODO IMPORTANT - this section shouldn't be included in the final code // It's needed here to differentiate step 2 (red) with the background color of the activity // It's should be commented out after the codes includes step 3 onwards Paint squaredPaint = new Paint(Paint.ANTI_ALIAS_FLAG); squaredPaint.setColor(Color.BLUE); framedCanvas.drawRoundRect(outerRect, 0f, 0f, squaredPaint); // End
Step 2. Draw an opaque rounded rectangle

// 2. Draw an opaque rounded rectangle link: // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1044s RectF innerRect = new RectF(border, border, size - border, size - border); Paint innerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); innerPaint.setColor(Color.RED); framedCanvas.drawRoundRect(innerRect, cornerRadius, cornerRadius, innerPaint);
Step 3. Set the Power Duff mode
Step 4. Draw a translucent rounded rectangle
From step 3 onwards, I will comment out "Dummy Step" in step 1. The reason why we put the code in the first place is ti differentiate the background color of the activity with the color of the widget.

// 1. Create offscreen bitmap link: http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1035s Bitmap framedOutput = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas framedCanvas = new Canvas(framedOutput); // End of Step 1 // Start - TODO IMPORTANT - this section shouldn't be included in the final code // It's needed here to differentiate step 2 (red) with the background color of the activity // It's should be commented out after the codes includes step 3 onwards // Paint squaredPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // squaredPaint.setColor(Color.BLUE); // framedCanvas.drawRoundRect(outerRect, 0f, 0f, squaredPaint); // End // 2. Draw an opaque rounded rectangle link: // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1044s RectF innerRect = new RectF(border, border, size - border, size - border); Paint innerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); innerPaint.setColor(Color.RED); framedCanvas.drawRoundRect(innerRect, cornerRadius, cornerRadius, innerPaint); // 3. Set the Power Duff mode // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1056s Paint outerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); outerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); // 4. Draw a translucent rounded rectangle link: // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU outerPaint.setColor(Color.argb(100, 0, 0, 0)); framedCanvas.drawRoundRect(outerRect, cornerRadius, cornerRadius, outerPaint);
Create Semi Transparent Rounded Border Image
Now that we have both semi transparent framed image and rounded image, we have to combine both images into one.
Last Step. Draw the frame on top of original bitmap


private void createFramedPhoto(int size) { Drawable imageDrawable = (image != null) ? new BitmapDrawable(image) : placeHolder; Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); RectF outerRect = new RectF(0, 0, size, size); float cornerRadius = size / 18f; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); canvas.drawRoundRect(outerRect, cornerRadius, cornerRadius, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); imageDrawable.setBounds(0, 0, size, size); // Save the layer to apply the paint canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG); imageDrawable.draw(canvas); canvas.restore(); // FRAMING THE PHOTO float border = size / 15f; // 1. Create offscreen bitmap link: // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1035s Bitmap framedOutput = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas framedCanvas = new Canvas(framedOutput); // End of Step 1 // Start - TODO IMPORTANT - this section shouldn't be included in the final code // It's needed here to differentiate step 2 (red) with the background color of the activity // It's should be commented out after the codes includes step 3 onwards // Paint squaredPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // squaredPaint.setColor(Color.BLUE); // framedCanvas.drawRoundRect(outerRect, 0f, 0f, squaredPaint); // End // 2. Draw an opaque rounded rectangle link: // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1044s RectF innerRect = new RectF(border, border, size - border, size - border); Paint innerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); innerPaint.setColor(Color.RED); framedCanvas.drawRoundRect(innerRect, cornerRadius, cornerRadius, innerPaint); // 3. Set the Power Duff mode // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU#t=1056s Paint outerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); outerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); // 4. Draw a translucent rounded rectangle link: // http://www.youtube.com/watch?feature=player_detailpage&v=jF6Ad4GYjRU outerPaint.setColor(Color.argb(100, 0, 0, 0)); framedCanvas.drawRoundRect(outerRect, cornerRadius, cornerRadius, outerPaint); // Draw the frame on top of original bitmap canvas.drawBitmap(framedOutput, 0f, 0f, null); framedPhoto = output; }
Tada!

Things to note:
  • You may notice that it's slightly different from what Eric Burke presented. It doesn't support editable photo. You may add OnClickListener and adjust the bottom border on Step 2.
  • No code refactoring is done here, so it needs one.
  • You may grab the source code at github
Thanks to Eric Burke

1 comment:

  1. Hi Bro,
    Great tutorial - the code doesnt work though,
    you have some problems with youre manifest file I couldnt understand...

    ReplyDelete