Câu trả lời:
Sau thời gian dài cân não, tôi đã tìm ra giải pháp
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;
}
static
và sử dụng trong một lớp tiện ích không khởi tạo của các phương thức tĩnh tương tự.
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
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;
}
Bạn có thể làm cho chế độ xem hình ảnh của mình hình tròn bằng cách sử dụng RoundedBitmapDrawable
đây là mã để đạt được roundImageview:
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 đã đưa ra nhận xét về câu trả lời ở trên và đề xuất sử dụng clipPath
làm tùy chọn để cắt hình ảnh dưới dạng hình tròn.
Sau đây là một triển khai rõ ràng của điều này:
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;
}
Điều này có thể được thêm vào một lớp tiện ích.
c.drawBitmap(b, 0, 0, null);
, sử dụng biến đổi danh tính mặc định.
Tôi nghĩ giải pháp này hoạt động tốt hơn với bất kỳ loại hình chữ nhật nào, hãy thay đổi kích thước pixel nếu bạn muốn hình ảnh nhỏ hoặc lớn:
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;
}
Điều này có thể được thực hiện trong xml mà không cần cắt ảnh bitmap thực tế, Bạn chỉ cần tạo một mặt nạ hình ảnh tròn và đặt lên hình ảnh thực tế của bạn. Đây là đoạn mã mà tôi đã sử dụng:
<?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"/>
<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>
Chế độ xem hình ảnh OutPut:
Hy vọng, nó có thể hữu ích cho ai đó !!! :)
bạn có thể sử dụng mã này, nó sẽ hoạt động
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;
}
bạn có thể sử dụng mã này, nó sẽ hoạt động
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;
}
Đây là biến thể Kotlin sử dụng phương thức mở rộng
/**
* 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
}
}
Đối với những người muốn có tâm của hình chữ nhật (tôi), hãy thêm cái này trước khi cắt:
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()
);
}
}
Dựa trên câu trả lời của [Jachumbelechao Unto Mantekilla], mã này hoạt động giống như một sự quyến rũ cho những người đang tìm kiếm giải pháp Kotlin:
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
}
Bây giờ, câu trả lời đúng:
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
}
gọi nó bằng mã này
holder.itemFriendImage.setImageBitmap(ImageConverter.getRoundedCornerBitmap(bitmap,600))
Tôi tin rằng giải pháp đơn giản nhất là tạo một BitmapShader của Bitmap của bạn, chuyển nó vào đối tượng paint của bạn và sau đó chỉ cần gọi một cái gì đó như canvas.drawCircle (cx, cy, radius, paint);
ví dụ
Paint p = new Paint();
p.setShader(new BitmapShader(myBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getHeight() / 2, p);
Đây là cách https://github.com/hdodenhof/CircleImageView cũng đã thực hiện, bạn có thể đọc mã nguồn tại đây: https://github.com/hdodenhof/CircleImageView/blob/master/circleimageview/src/main/java /de/hdodenhof/circleimageview/CircleImageView.java
**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);
}
Không chắc đây là một câu hỏi lập trình nhưng ...
Giải pháp dễ nhất là làm cho khu vực bên ngoài trong suốt trong bitmap nguồn. Nếu không, bạn sẽ phải tính toán những pixel nào nằm ngoài vòng tròn và đặt alpha cho phù hợp (alpha = 0 để có độ trong suốt hoàn toàn).