Border over a bitmap with rounded corners in Android-ThrowExceptions

Exception or error:

I used the below to make a bitmap with rounded corners. Now I want to draw a line around the bitmap.

private BitmapDrawable roundCornered(BitmapDrawable scaledBitmap, int i) {

        Bitmap bitmap = scaledBitmap.getBitmap();

        result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
                Bitmap.Config.ARGB_8888);
        canvas = new Canvas(result);

        color = 0xff424242;
        paint = new Paint();
        rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        rectF = new RectF(rect);
        roundPx = i;
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.BLUE);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        BitmapDrawable finalresult = new BitmapDrawable(result);
        return finalresult;
    }

I got the image below, but my actual need is that I must draw a border around the image.

How to solve:

I put the following together for myself.

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int color, int cornerDips, int borderDips, Context context) {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int borderSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) borderDips,
            context.getResources().getDisplayMetrics());
    final int cornerSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) cornerDips,
            context.getResources().getDisplayMetrics());
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
    final RectF rectF = new RectF(rect);

    // prepare canvas for transfer
    paint.setAntiAlias(true);
    paint.setColor(0xFFFFFFFF);
    paint.setStyle(Paint.Style.FILL);
    canvas.drawARGB(0, 0, 0, 0);
    canvas.drawRoundRect(rectF, cornerSizePx, cornerSizePx, paint);

    // draw bitmap
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    // draw border
    paint.setColor(color);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth((float) borderSizePx);
    canvas.drawRoundRect(rectF, cornerSizePx, cornerSizePx, paint);

    return output;
}

Credits, of course, to http://ruibm.com/?p=184

###

How about to prepare 9-patch image like below and set it as a background by using android:background

enter image description here

###

I use BitmapShader and drawRoundRect do it and it work for me, look at the screenshot

enter image description here

RectF roundRect; // the Rect you have to draw into
Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

// draw the border at bottom
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mBorderColor);
canvas.drawRoundRect(roundRect, mRadius, mRadius, mPaint);

// ------------------ draw scheme bitmap
roundRect.set(itemRect.left + mBorderSize, itemRect.top + mBorderSize, itemRect.right - mBorderSize, itemRect.bottom - mBorderSize);
Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
canvas.drawRoundRect(roundRect, mRadius, mRadius, mPaint);
mPaint.setShader(null);

###

Unfortunately there’s no nice and neat “border” parameter in Android, but the simplest way to do it is to encase that within another layout, set the background of the parent layout to your border color/drawable and then set a padding on it. The padding will appear around your BitmapDrawable.

###

I did many search to implement that effect by code, before I found another way but it’s not perfect enough, you can see the jaggy on each corner, I set Paint.setAntiAlias(true), Paint.setDither(true), Paint.setFilterBitmap(true), but It doesn’t work, so I hope somebody can help me.
enter image description here

RectF roundRect = new RectF(itemRect);

Bitmap bitmap = scheme.getSchemeBitmap(getResources());

mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mSchemeSelectedColor);
canvas.drawRoundRect(roundRect, mSchemeCornerRadius, mSchemeCornerRadius, mPaint);

roundRect.set(itemRect.left + mBorderSize, itemRect.top + mBorderSize, itemRect.right - mBorderSize, itemRect.bottom - mBorderSize);
Path clipPath = new Path();
clipPath.addRoundRect(roundRect, mSchemeCornerRadius, mSchemeCornerRadius, Path.Direction.CW);
canvas.save(Canvas.CLIP_SAVE_FLAG);
canvas.clipPath(clipPath);
canvas.drawBitmap(bitmap, null, roundRect, mPaint);
canvas.restore();

###

my way:

 public static Bitmap getRoundedCornerBitmap1(Bitmap bitmap, int color, int cornerDips, int borderDips) {


            Bitmap output = Bitmap.createBitmap(bitmap.getWidth()+2*borderDips,
                    bitmap.getHeight()+2*borderDips,
                    Bitmap.Config.ARGB_8888);

            Canvas canvas = new Canvas(output);

            canvas.drawColor(Color.TRANSPARENT);

            final RectF rectF = new RectF(0, 0, output.getWidth(), output.getHeight());
            final Paint paint = new Paint();
            // prepare canvas for transfer
            paint.setAntiAlias(true);
            paint.setStrokeWidth((float) borderDips);
            paint.setColor(Color.WHITE);
            paint.setStyle(Paint.Style.FILL);

            canvas.drawRoundRect(rectF, borderDips, borderDips, paint);

            canvas.drawBitmap(bitmap, borderDips, borderDips, null);
            bitmap.recycle();
            return output;
        }

Result

enter image description here

Leave a Reply

Your email address will not be published. Required fields are marked *