Please try this modified code. I've tried explaining the changes in the comments. Sorry if they are insufficient:
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.dog);
//
// vvvv Commented out vvvv
/*
* Reason: The new Bitmap must be larger than the bitmap around
* which the circle must be drawn.
*/
// Bitmap workingBitmap = Bitmap.createBitmap(bitmap);
// Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888,
// true);
// Canvas canvas = new Canvas(mutableBitmap);
// ^^^^ Commented out ^^^^
//
// vvvv Added vvvv
// This is the total (Right + left) extra space on the sides;
int padding = 30;
// Since the Paint is going to draw a noticeably thick line, the thickness must be included in the calculations
int strokeWidth = 6;
/*
* Calculating single dimension since the bitmap must have a square shape for the circle to fit.
* Also account for the padding and the stroke width;
*/
int bitmapSize = Math.max(bitmap.getWidth(), bitmap.getHeight()) + padding + strokeWidth;
Bitmap workingBitmap = Bitmap.createBitmap(bitmapSize, bitmapSize,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(workingBitmap);
// ^^^^ Added ^^^^
//
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
//
// paint.setStrokeWidth(6);
paint.setStrokeWidth(strokeWidth);
//
// canvas.drawCircle(centerCoordinate, centerCoordinate,
// centerCoordinate+15, paint);
/*
* Calculate exact top left position in the result Bitmap to draw the original Bitmap
*/
canvas.drawBitmap(bitmap, (bitmapSize - bitmap.getWidth()) / 2.0f,
(bitmapSize - bitmap.getHeight()) / 2.0f, paint);
//
// int centerCoordinate = mutableBitmap.getWidth()/2;
int centerCoordinate = bitmapSize / 2;
//
//canvas.drawCircle(centerCoordinate, centerCoordinate,
// centerCoordinate+15, paint);
/*
* Draw the circle but account for the stroke width of the paint or else the circle will flatten on the edges of the Bitmap.
*/
canvas.drawCircle(centerCoordinate, centerCoordinate,
centerCoordinate - (strokeWidth/2.0f), paint);
// equivalent to imageView.setImageBitmap
// views.setImageViewBitmap(R.id.icon, mutableBitmap);
views.setImageViewBitmap(R.id.icon, workingBitmap);
Also in the layout for the ImageView
add:
android:scaleType="fitXY"
Edit:
To keep the inner bitmap size fixed and only vary the circle size, first, the ImageView
and its LinearLayout
container cannot have a fixed size. Change all of those layout width and height values in the layout to "wrap_content"
.
Secondly since the image resource for "bitmap"
is of an unknown size, bitmap
will have to be loaded with a scaled down version of the resource that fits the maximum allowable dimension for the bitmap only, which in your case is 30px. This can be done by replacing:
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.dog);
With the following code:
//
// Value to hold the required image dimension;
int requiredImageDimension = 30;
// Decode the Bitmap resource with the set options.
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.dog);
// Scaled bitmap reference;
Bitmap bitmap = null;
// Check if the largest dimension is the width;
if (originalBitmap.getWidth() > originalBitmap.getHeight()) {
// Force the width to the maximum allowable size and calculate
// the scaled height of the Bitmap;
bitmap = Bitmap.createScaledBitmap(originalBitmap,
requiredImageDimension,
originalBitmap.getHeight() * requiredImageDimension
/ originalBitmap.getWidth(), true);
}
// If the width and height are equal;
else if(originalBitmap.getWidth() == originalBitmap.getHeight()){
// Force the width and height to the maximum allowable size;
bitmap = Bitmap.createScaledBitmap(originalBitmap,
requiredImageDimension,
requiredImageDimension, true);
}
// If the largest dimension is the height;
else {
// Force the height to the maximum allowable size and calculate
// the scaled width of the Bitmap;
bitmap = Bitmap.createScaledBitmap(originalBitmap,
originalBitmap.getWidth() * requiredImageDimension
/ originalBitmap.getHeight(),
requiredImageDimension, true);
}
So now you get a scaled down version of the original bitmap resource which will be pasted on the larger workingBitmap
and loaded into the ImageView
which will resize itself to accommodate the bitmap without scaling.