ビットマップがあり、このビットマップから円形領域を切り取りたい。円の外側のすべてのピクセルは透明でなければなりません。これどうやってするの?
長いブレーンストーミングの後、私は解決策を見つけました
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;
}
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;
}
RoundedBitmapDrawable を使用して、imageviewを円形にすることができます。
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は、上記の回答について、画像を円として切り取るためのオプションとしてclipPath
を使用することを提案するコメントを作成しました。
以下は、これのクリーンな実装です。
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;
}
これは、ユーティリティクラスに追加できます。
私はこの解決策があらゆるタイプの長方形でうまく機能すると思います、あなたが画像を小さくしたり大きくしたい場合はピクセルサイズを変更してください:
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;
}
これは、実際のビットマップをトリミングせずに、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"/>
<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:
希望、それは誰かに役立つかもしれません!!! :)
このコードを使用できます、動作します
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;
}
このコードを使用できます、動作します
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;
}
不要になったらbitmap.recycle()
を追加することをお勧めします。OutOfMemoryエラーを防ぐことができます。
[Jachumbelechao Unto Mantekilla]の回答に基づいて、このコードは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
}
四角形(私)の中心が必要な場合は、カットする前にこれを追加します。
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()
);
}
}
今、正しい答え:
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;
}
拡張メソッドを使用したKotlinバリアント
/**
* 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
}
}
コタン機能
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
}
このコードで呼び出す
holder.itemFriendImage.setImageBitmap(ImageConverter.getRoundedCornerBitmap(bitmap,600))
最も簡単な解決策は、ビットマップのBitmapShaderを作成し、それをPaintオブジェクトに渡し、単純にcanvas.drawCircle(cx、cy、radius、Paint)のようなものを呼び出すことだと思います。
例えば
Paint p = new Paint();
p.setShader(new BitmapShader(myBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getHeight() / 2, p);
これは https://github.com/hdodenhof/CircleImageView の方法でもあります。ソースコードはここで読むことができます: 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);
}