如何使圆角的ImageView?

在Android中,默认情况下ImageView是一个矩形。 我怎样才能使它在ImageView中的一个圆角的矩形(剪切掉我的位图的所有四个角落是圆角矩形)?

**In Layout** Make your ImageView like  **And Create a Class** package com.example; import java.util.Formatter.BigDecimalLayoutForm; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.ImageView; public class CircularImageView extends ImageView { public CircularImageView(Context context) { super(context); } public CircularImageView(Context context, AttributeSet attrs) { super(context, attrs); } public CircularImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } Bitmap b = ((BitmapDrawable) drawable).getBitmap(); Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); int w = getWidth(), h = getHeight(); Bitmap roundBitmap = getRoundBitmap(bitmap, w); canvas.drawBitmap(roundBitmap, 0, 0, null); } public static Bitmap getRoundBitmap(Bitmap bmp, int radius) { Bitmap sBmp; if (bmp.getWidth() != radius || bmp.getHeight() != radius) { float smallest = Math.min(bmp.getWidth(), bmp.getHeight()); float factor = smallest / radius; sBmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false); } else { sbmp = bmp; } Bitmap output = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xffa19774; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, radius, radius); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(Color.parseColor("#BAB399")); canvas.drawCircle(radius / 2 + 0.7f, radius / 2 + 0.7f, radius / 2 + 0.1f, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(sBmp, rect, rect, paint); return output; } } 

尝试这个

 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(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final 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")); canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f, finalBitmap.getHeight() / 2 + 0.7f, finalBitmap.getWidth() / 2 + 0.1f, paint); paint.setXfermode(new PorterDuffXfermode( android.graphics.PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(finalBitmap, rect, rect, paint); return output; 
  /** * Background Async task to load user profile picture from url */ private class LoadProfileImage extends AsyncTask { 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); } } 

虽然前两个答案的工作,我想多描述一下。 比方说,你的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; } 

然后,你应该写一个方法来缩放图像,并围绕其角落。 这里宽度和高度是位图的新维度(更小或更大)。 在下面的例子中,我只围绕两个顶角

 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; } 

用CardView包装ImageView并设置cardCornerRadius

    

这里我的解决方案

  

而在java代码中:

 public class RadiusCornerImageView extends android.support.v7.widget.AppCompatImageView { private int cornerRadiusDP = 0; // dp private int corner_radius_position; public RadiusCornerImageView(Context context) { super(context); } public RadiusCornerImageView(Context context, AttributeSet attrs) { super(context, attrs); } public RadiusCornerImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RadiusCornerImageView, 0, 0); try { cornerRadiusDP = typeArray.getInt(R.styleable.RadiusCornerImageView_corner_radius_dp, 0); corner_radius_position = typeArray.getInteger(R.styleable.RadiusCornerImageView_corner_radius_position, 0); } finally { typeArray.recycle(); } } @Override protected void onDraw(Canvas canvas) { float radiusPx = AndroidUtil.dpToPx(getContext(), cornerRadiusDP); Path clipPath = new Path(); RectF rect = null; if (corner_radius_position == 0) { // all // round corners on all 4 angles rect = new RectF(0, 0, this.getWidth(), this.getHeight()); } else if (corner_radius_position == 1) { // round corners only on top left and top right rect = new RectF(0, 0, this.getWidth(), this.getHeight() + radiusPx); } else { throw new IllegalArgumentException("Unknown corner_radius_position = " + corner_radius_position); } clipPath.addRoundRect(rect, radiusPx, radiusPx, Path.Direction.CW); canvas.clipPath(clipPath); super.onDraw(canvas); } 

}

感谢melanke,您可以使用自定义类创建一个自定义的圆形ImageView

 import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; public class MLRoundedImageView extends android.support.v7.widget.AppCompatImageView { public MLRoundedImageView(Context context) { super(context); } public MLRoundedImageView(Context context, AttributeSet attrs) { super(context, attrs); } public MLRoundedImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } Bitmap b = ((BitmapDrawable) drawable).getBitmap(); Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); int w = getWidth(), h = getHeight(); Bitmap roundBitmap = getCroppedBitmap(bitmap, w); canvas.drawBitmap(roundBitmap, 0, 0, null); } public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) { Bitmap sbmp; if (bmp.getWidth() != radius || bmp.getHeight() != radius) { float smallest = Math.min(bmp.getWidth(), bmp.getHeight()); float factor = smallest / radius; sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false); } else { sbmp = bmp; } Bitmap output = Bitmap.createBitmap(radius, radius, Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xffa19774; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, radius, radius); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(Color.parseColor("#BAB399")); canvas.drawCircle(radius / 2 + 0.7f, radius / 2 + 0.7f, radius / 2 + 0.1f, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(sbmp, rect, rect, paint); return output; } } 

然后在XML中使用它:

  

资源

科特林

 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 Circular,我们可以使用以下命令更改cornerRadius

 rounded.isCircular = true