Hi guys I a have contact list view with Quick contact badge.It displaying square images but my requirement is to show circular quick contact badge (like below screen shot). Plz let me know how can I achieve this. Thanks in advance.
Below are two methods for creating circular images. you just have to pass bitmap image to make it circular.
/**
* To make image in a round shape. Use this method if you want to specify required height and width
*
* #param i
*/
public static Bitmap getRoundedShape(Bitmap scaleBitmapImage, int i) {
int targetWidth = i;
int targetHeight = i;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) targetWidth - 1) / 2,
((float) targetHeight - 1) / 2,
(Math.min(((float) targetWidth), ((float) targetHeight)) / 2),
Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(),
sourceBitmap.getHeight()), new Rect(0, 0, targetWidth,
targetHeight), null);
return targetBitmap;
}
/**
* To make image in a round shape
*/
public static 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.drawRoundRect(rectF, roundPx, roundPx, paint);
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);
// Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
// return _bmp;
return output;
}
Now a days, you should look into RoundedBitmapDrawable. A round drawable can easily be created by
Bitmap bitmap = <the bitmap you want to be circular>
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
Don't forget (Thanks Gil SH for pointing this out):
drawable.setCornerRadius(Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f);
Source: https://developer.android.com/reference/android/support/v4/graphics/drawable/RoundedBitmapDrawable.html
I am doing camera application.i have capture and crop image in square shape. But i need oval shape or human face shape. How is it come ?
I have used following method and passed my captured bitmap image to this method. And it will work.
public Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
int targetWidth = 125;
int targetHeight = 125;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
targetHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(
((float) targetWidth - 1) / 2,
((float) targetHeight - 1) / 2,
(Math.min(((float) targetWidth), ((float) targetHeight)) / 2),
Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(
sourceBitmap,
new Rect(0, 0, sourceBitmap.getWidth(), sourceBitmap
.getHeight()), new Rect(0, 0, targetWidth,
targetHeight), p);
return targetBitmap;
}
And the output is as follows:-
I used following in one of my project. May be this helps you.
public Drawable getRoundedCornerImage(Drawable bitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable)bitmapDrawable).getBitmap();
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());
final RectF rectF = new RectF(rect);
final float roundPx = 10;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
Drawable image = new BitmapDrawable(output);
return image;
}
Explore com.android.camera.CropImage.java sources. It can crop circle images.
// if we're circle cropping we'll want alpha which is the third param here
464 mCroppedImage = Bitmap.createBitmap(width, height,
465 mCircleCrop ?
466 Bitmap.Config.ARGB_8888 :
467 Bitmap.Config.RGB_565);
468 Canvas c1 = new Canvas(mCroppedImage);
469 c1.drawBitmap(mBitmap, r, new Rect(0, 0, width, height), null);
470
471 if (mCircleCrop) {
472 // OK, so what's all this about?
473 // Bitmaps are inherently rectangular but we want to return something
474 // that's basically a circle. So we fill in the area around the circle
475 // with alpha. Note the all important PortDuff.Mode.CLEAR.
476 Canvas c = new Canvas (mCroppedImage);
477 android.graphics.Path p = new android.graphics.Path();
478 p.addCircle(width/2F, height/2F, width/2F, android.graphics.Path.Direction.CW);
479 c.clipPath(p, Region.Op.DIFFERENCE);
480
481 fillCanvas(width, height, c);
482 }
#vokilam you are right; I just explored into code and found a way to work around...
Just include this line in the main Activity
intent.putExtra(CropImage.CIRCLE_CROP, "circleCrop");
But you will only get circles, not oval; so #amarnathreddy you cannot cut perfect human face with this; instead go for Grabcut of OpenCv
Try with this ...to crop in human face shape
Uri ImageCaptureUri = Uri.fromFile(new File("filepath");
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
intent.setData(ImageCaptureUri);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, 1);
For an oval shape try this android function or download demo here
public static Bitmap getOvalCroppedBitmap(Bitmap bitmap, int radius) {
Bitmap finalBitmap;
if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
false);
else
finalBitmap = bitmap;
Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
finalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
finalBitmap.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
RectF oval = new RectF(0, 0, 130, 150);
canvas.drawOval(oval, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(finalBitmap, rect, oval, paint);
return output;
}
The above function creates a uniform oval shape in android programmatically.
call your function onCreate function and pass the image to crop oval shape as a bitmap image
Read more
I have a bitmap and I want to crop a circular region from this bitmap. All pixels outside the circle should be transparent. How can I do this?
After long brainstorming I have found the solution
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.drawRoundRect(rectF, roundPx, roundPx, paint);
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);
//Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
//return _bmp;
return output;
}
to generate Circle from rectangles
public static Bitmap getCircularBitmap(Bitmap bitmap) {
Bitmap output;
if (bitmap.getWidth() > bitmap.getHeight()) {
output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Config.ARGB_8888);
} else {
output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), 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());
float r = 0;
if (bitmap.getWidth() > bitmap.getHeight()) {
r = bitmap.getHeight() / 2;
} else {
r = bitmap.getWidth() / 2;
}
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(r, r, r, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
You Can make your imageview circular using RoundedBitmapDrawable
here is the code for achieving roundedImageview:
ImageView profilePic=(ImageView)findViewById(R.id.user_image);
//get bitmap of the image
Bitmap imageBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.large_icon);
RoundedBitmapDrawable roundedBitmapDrawable=RoundedBitmapDrawableFactory.create(getResources(), imageBitmap);
//setting radius
roundedBitmapDrawable.setCornerRadius(50.0f);
roundedBitmapDrawable.setAntiAlias(true);
profilePic.setImageDrawable(roundedBitmapDrawable);
#Gene made a comment on the answer above that suggested using clipPath as an option for cropping an image as a circle.
The following is a clean implementation of this:
public static Bitmap GetBitmapClippedCircle(Bitmap bitmap) {
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
final Bitmap outputBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
final Path path = new Path();
path.addCircle(
(float)(width / 2)
, (float)(height / 2)
, (float) Math.min(width, (height / 2))
, Path.Direction.CCW);
final Canvas canvas = new Canvas(outputBitmap);
canvas.clipPath(path);
canvas.drawBitmap(bitmap, 0, 0, null);
return outputBitmap;
}
This could be added to a utility class.
I think this solution works better with any type of rectangle, change the pixel size if you want image small or large :
public static Bitmap getCircleBitmap(Bitmap bm) {
int sice = Math.min((bm.getWidth()), (bm.getHeight()));
Bitmap bitmap = ThumbnailUtils.extractThumbnail(bm, sice, sice);
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffff0000;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setFilterBitmap(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth((float) 4);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
This can be easlity done in xml as well without cropping the actual bitmap, You just need to create a circular image mask and place over your actual image. Here is the piece of code which i used:
circle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#00FFFFFF" android:endColor="#00FFFFFF"
android:angle="270"/>
<stroke android:width="10dp" android:color="#FFAAAAAA"/>
your_layout.xml (Ignore "android:scaleType="fitXY"" if you don't need it)
<RelativeLayout
android:id="#+id/icon_layout"
android:layout_width="#dimen/icon_mask"
android:layout_height="#dimen/icon_mask"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<ImageView
android:id="#+id/icon"
android:layout_width="#dimen/icon"
android:layout_height="#dimen/icon"
android:layout_centerInParent="true"
android:scaleType="fitXY" >
</ImageView>
<ImageView
android:id="#+id/icon_mask"
android:layout_width="#dimen/icon_mask"
android:layout_height="#dimen/icon_mask"
android:layout_centerInParent="true"
android:background="#drawable/circle"
android:scaleType="fitXY" >
</ImageView>
</RelativeLayout>
dimen.xml
<dimen name="icon">36dp</dimen>
<dimen name="icon_mask">55dp</dimen>
OutPut Image View:
Hope, It might be useful for someone!!! :)
you can use this code, it will work
private Bitmap getCircleBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
you can use this code, it will work
public Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
int targetWidth = 110;
int targetHeight = 110;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
targetHeight,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) targetWidth - 1) / 2,
((float) targetHeight - 1) / 2,
(Math.min(((float) targetWidth),
((float) targetHeight)) / 2),
Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap,
new Rect(0, 0, sourceBitmap.getWidth(),
sourceBitmap.getHeight()),
new Rect(0, 0, targetWidth, targetHeight), new Paint(Paint.FILTER_BITMAP_FLAG));
return targetBitmap;
}
I believe the easiest solution is to create a BitmapShader of your Bitmap, pass it to your paint object and then simply call something like canvas.drawCircle(cx, cy, radius, paint);
for example
Paint p = new Paint();
p.setShader(new BitmapShader(myBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getHeight() / 2, p);
This is how https://github.com/hdodenhof/CircleImageView also has done it,
you can read the source code here:
https://github.com/hdodenhof/CircleImageView/blob/master/circleimageview/src/main/java/de/hdodenhof/circleimageview/CircleImageView.java
I recommend adding bitmap.recycle() if you don't need it anymore, it will prevent OutOfMemory error.
Here is Kotlin variant using extension method
/**
* Creates new circular bitmap based on original one.
*/
fun Bitmap.getCircularBitmap(config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap {
// circle configuration
val circlePaint = Paint().apply { isAntiAlias = true }
val circleRadius = Math.max(width, height) / 2f
// output bitmap
val outputBitmapPaint = Paint(circlePaint).apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) }
val outputBounds = Rect(0, 0, width, height)
val output = Bitmap.createBitmap(width, height, config)
return Canvas(output).run {
drawCircle(circleRadius, circleRadius, circleRadius, circlePaint)
drawBitmap(this#getCircularBitmap, outputBounds, outputBounds, outputBitmapPaint)
output
}
}
For peaple who want the center of the rectangle (me), add this before cutting:
public static Bitmap cropBitmapToBlock(Bitmap bitmap) {
if (bitmap.getWidth() >= bitmap.getHeight()){
return Bitmap.createBitmap(
bitmap,
bitmap.getWidth()/2 - bitmap.getHeight()/2,
0,
bitmap.getHeight(),
bitmap.getHeight()
);
}else{
return Bitmap.createBitmap(
bitmap,
0,
bitmap.getHeight()/2 - bitmap.getWidth()/2,
bitmap.getWidth(),
bitmap.getWidth()
);
}
}
Android Crop Center of Bitmap
Based on [Jachumbelechao Unto Mantekilla] answer, this code works like a charm for people looking for a Kotlin solution:
fun cropCircleFromBitmap(originalBitmap: Bitmap): Bitmap {
val size = Math.min(originalBitmap.width, originalBitmap.height)
val bitmap = ThumbnailUtils.extractThumbnail(originalBitmap, size, size)
var output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
val rectF = RectF(rect)
paint.isAntiAlias = true
paint.isDither = true
paint.isFilterBitmap = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = 0xffff0000.toInt()
canvas.drawOval(rectF, paint)
paint.color = Color.BLUE
paint.style = Paint.Style.STROKE
paint.strokeWidth = 4f
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
canvas.drawBitmap(bitmap, rect, rect, paint)
return output
}
Now, Right answer:
private Bitmap getCroppedBitmap(Bitmap bitmap, Integer cx, Integer cy, Integer radius) {
int diam = radius << 1;
Bitmap targetBitmap = Bitmap.createBitmap(diam, diam, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
final int color = 0xff424242;
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(radius, radius, radius, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, -cx+radius, -cy+radius, paint);
return targetBitmap;
}
Kotin Fucntion
fun getRoundedCornerBitmap(bitmap: Bitmap, pixels: Int): Bitmap {
val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val color = -0xbdbdbe
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
val rectF = RectF(rect)
val roundPx = pixels.toFloat()
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = color
canvas.drawRoundRect(rectF, roundPx, roundPx, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
return output
}
call it by this code
holder.itemFriendImage.setImageBitmap(ImageConverter.getRoundedCornerBitmap(bitmap,600))
**Jst Add this to your image Id and get the circuler image.**
imgUserProfile.setImageBitmap(getCircularCenterCropBitmap(bitmap, (int) (150 * denisty)));
Method:-
public void Bitmap getCircularCenterCropBitmap(Bitmap originalBmp, int diameter) {
Bitmap resizedBmp = BitmapUtils.getScaledCroppedBitmap(originalBmp, diameter, diameter);
return BitmapUtils.getRoundedCircularBitmap(resizedBmp, diameter / 2);
}
For kotlin:
private fun getCircularBitmap(bitmap: Bitmap): Bitmap? {
val output = Bitmap.createBitmap(
bitmap.width,
bitmap.height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(output)
val color = -0xbdbdbe
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = color
canvas.drawCircle(
(bitmap.width / 2).toFloat(), (bitmap.height / 2).toFloat(), (
bitmap.width / 2).toFloat(), paint
)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
return output
}
kotlin, put it in Ext.kt
private fun Bitmap.getCircledBitmap(): Bitmap {
val output = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint()
val rect = Rect(0, 0, this.width, this.height)
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
canvas.drawCircle(this.width / 2f, this.height / 2f, this.width / 2f, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(this, rect, rect, paint)
return output
}
Not sure this is a programming question but...
The easiest solution would be to make the outside area transparent in the source bitmap. Otherwise, you'll have to calculate which pixels are outside of the circle, and set the alpha accordingly (alpha = 0 for full transparency).