在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
当前回答
/**
* 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);
}
}
其他回答
科特林
import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
rounded.cornerRadius = 20f
profileImageView.setImageDrawable(rounded)
为了使ImageView成为圆形,我们可以改变拐角半径:
rounded.isCircular = true
最近,还有另一种方法——使用Glide的生成API。它需要一些初始的工作,但它给了你Glide所有的力量,以及做任何事情的灵活性,因为你重写了实际的代码,所以我认为从长远来看,这是一个很好的解决方案。另外,使用非常简单和整洁。
首先,设置Glide版本4+:
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
然后创建Glid的app模块类来触发注释处理:
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}
然后创建实际工作的Glide扩展。你可以自定义它来做任何你想做的事情:
@GlideExtension
public class MyGlideExtension {
private MyGlideExtension() {}
@NonNull
@GlideOption
public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) {
int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
return options.transforms(new RoundedCorners(px));
}
}
添加这些文件之后,构建您的项目。
然后像这样在你的代码中使用它:
GlideApp.with(this)
.load(imageUrl)
.roundedCorners(getApplicationContext(), 5)
.into(imageView);
虽然前两个答案是可行的,但我希望再多描述一点。 比如说,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;
}
在glide库和RoundedBitmapDrawableFactory类的帮助下,很容易实现。您可能需要创建圆形占位符映像。
Glide.with(context)
.load(imgUrl)
.asBitmap()
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.into(new BitmapImageViewTarget(imgProfilePicture) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
Bitmap.createScaledBitmap(resource, 50, 50, false));
drawable.setCornerRadius(10); //drawable.setCircular(true);
imgProfilePicture.setImageDrawable(drawable);
}
});
你可以很容易地使用roundedImageView库:
compile 'com.makeramen:roundedimageview:2.3.0'
然后:
<com.makeramen.roundedimageview.RoundedImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/img_episode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="7dp"
app:riv_border_color="@color/colorPrimary"
app:riv_border_width="1dip"
app:riv_corner_radius="10dip"
app:riv_mutate_background="true"
/>