在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
当前回答
虽然前两个答案是可行的,但我希望再多描述一点。 比如说,ImageView所在的地方有一个活动或片段。您希望绘制图像并按比例缩放。然后你应该在onCreate或onCreateView中写入如下代码:
LinearLayout rootLayout = (LinearLayout) findViewById(R.id.rootLayout);
ImageView image = (ImageView) findViewById(R.id.image);
// Wait till an activity is visible and image can be measured.
rootLayout.post(new Runnable() {
@Override
public void run() {
// Setting ImageView height with aspect ratio.
Drawable drawable = ContextCompat.getDrawable(getActivity(), R.drawable.your_image);
int height = getImageViewHeight(drawable, image);
// Rounding image corners.
float radius = getResources().getDimension(R.dimen.your_radius_in_dp);
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap result = getRoundedBitmap(bitmap, image.getWidth(), height, radius);
image.setImageBitmap(result);
}
});
其中设置新的图像高度为:
public static int getImageViewHeight(Drawable drawable, ImageView imageView) {
imageView.setImageDrawable(drawable);
int width = drawable.getIntrinsicWidth();
int height = 0;
if (width > 0) {
height = (drawable.getIntrinsicHeight() * imageView.getWidth()) / width;
imageView.getLayoutParams().height = height;
imageView.requestLayout();
}
return height;
}
然后,您应该编写一个方法来缩放图像并使其圆角。这里的width和height是位图的新维度(更小或更大)。在下面的例子中,我只圆角上的两个角。
private Bitmap getRoundedBitmap(Bitmap bitmap, int width, int height, float radius) {
// Create scaled bitmap.
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
BitmapShader shader = new BitmapShader(scaledBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
// First make all corners round.
canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paint);
// Then draw bottom rectangle.
canvas.drawRect(0, height - radius, radius, height, paint);
canvas.drawRect(width - radius, height - radius, width, height, paint);
return result;
}
其他回答
/**
* Background Async task to load user profile picture from url
*/
private class LoadProfileImage extends AsyncTask<String, Void, RoundedBitmapDrawable> {
ImageView profileImageView;
public LoadProfileImage(ImageView profileImageView) {
this.profileImageView = profileImageView;
}
protected RoundedBitmapDrawable doInBackground(String... urls) {
String photoUrl = urls[0];
RoundedBitmapDrawable profileRoundedDrawable = null;
try {
InputStream inputStream = new java.net.URL(photoUrl).openStream();
Resources res = getResources();
profileRoundedDrawable = RoundedBitmapDrawableFactory.create(res, inputStream);
profileRoundedDrawable.setCircular(true);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return profileRoundedDrawable;
}
protected void onPostExecute(RoundedBitmapDrawable result) {
profileImageView.setImageDrawable(result);
}
}
对于上面提到的乔治·沃尔特斯二世,我只是把他的答案扩展了一下,以支持不同的圆角。这可以进一步优化(一些目标矩形重叠),但不是很多。
我知道这个线程有点老了,但它是谷歌上关于如何在Android上圆角ImageViews的查询的顶级结果之一。
/**
* Use this method to scale a bitmap and give it specific rounded corners.
* @param context Context object used to ascertain display density.
* @param bitmap The original bitmap that will be scaled and have rounded corners applied to it.
* @param upperLeft Corner radius for upper left.
* @param upperRight Corner radius for upper right.
* @param lowerRight Corner radius for lower right.
* @param lowerLeft Corner radius for lower left.
* @param endWidth Width to which to scale original bitmap.
* @param endHeight Height to which to scale original bitmap.
* @return Scaled bitmap with rounded corners.
*/
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft,
float upperRight, float lowerRight, float lowerLeft, int endWidth,
int endHeight) {
float densityMultiplier = context.getResources().getDisplayMetrics().density;
// scale incoming bitmap to appropriate px size given arguments and display dpi
bitmap = Bitmap.createScaledBitmap(bitmap,
Math.round(endWidth * densityMultiplier),
Math.round(endHeight * densityMultiplier), true);
// create empty bitmap for drawing
Bitmap output = Bitmap.createBitmap(
Math.round(endWidth * densityMultiplier),
Math.round(endHeight * densityMultiplier), Config.ARGB_8888);
// get canvas for empty bitmap
Canvas canvas = new Canvas(output);
int width = canvas.getWidth();
int height = canvas.getHeight();
// scale the rounded corners appropriately given dpi
upperLeft *= densityMultiplier;
upperRight *= densityMultiplier;
lowerRight *= densityMultiplier;
lowerLeft *= densityMultiplier;
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
// fill the canvas with transparency
canvas.drawARGB(0, 0, 0, 0);
// draw the rounded corners around the image rect. clockwise, starting in upper left.
canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint);
canvas.drawCircle(width - upperRight, upperRight, upperRight, paint);
canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint);
canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint);
// fill in all the gaps between circles. clockwise, starting at top.
RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2);
RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight);
RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height);
RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft);
canvas.drawRect(rectT, paint);
canvas.drawRect(rectR, paint);
canvas.drawRect(rectB, paint);
canvas.drawRect(rectL, paint);
// set up the rect for the image
Rect imageRect = new Rect(0, 0, width, height);
// set up paint object such that it only paints on Color.WHITE
paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET));
// draw resized bitmap onto imageRect in canvas, using paint as configured above
canvas.drawBitmap(bitmap, imageRect, imageRect, paint);
return output;
}
如果你正在使用格莱德图书馆,这将是有帮助的:
Glide.with(getApplicationContext())
.load(image_url)
.asBitmap()
.centerCrop()
.into(new BitmapImageViewTarget(imageView) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource);
circularBitmapDrawable.setCornerRadius(dpToPx(10));
circularBitmapDrawable.setAntiAlias(true);
imageView.setImageDrawable(circularBitmapDrawable);
}
});
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
使用这个得到圆形图像与边界
public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) {
if (bitmap == null || bitmap.isRecycled()) {
return null;
}
int borderWidth=(int)(bitmap.getWidth()/40);
final int width = bitmap.getWidth() + borderWidth;
final int height = bitmap.getHeight() + borderWidth;
Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP,
TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
Canvas canvas = new Canvas(canvasBitmap);
float radius = width > height ? ((float) height) / 2f
: ((float) width) / 2f;
canvas.drawCircle(width / 2, height / 2, radius, paint);
paint.setShader(null);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(bordercolor);
paint.setStrokeWidth(borderWidth);
canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2,
paint);
return canvasBitmap;
}
罗曼盖伊就在那里。
缩小版如下。
Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();
Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);
imageView.setImageBitmap(bitmapRounded);