如何用Glide库将图像四舍五入?

那么,有人知道如何用Glide显示圆angular的图像吗? 我正在用Glide加载图片,但是我不知道如何将圆形parameter passing给这个库。

我需要显示图像,如下面的例子:

在这里输入图像说明

滑翔V4:

Glide.with(context).load(url).apply(RequestOptions.circleCropTransform()).into(imageView); 

Glide V3:

您可以将RoundedBitmapDrawable用于带有Glide的圆形图像。 没有自定义ImageView是必需的。

  Glide.with(context).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource); circularBitmapDrawable.setCircular(true); imageView.setImageDrawable(circularBitmapDrawable); } }); 

检查这个职位,滑行vs毕加索 …
编辑 :链接的post不会在库中调出一个重要的区别。 滑翔自动进行回收。 有关更多信息,请参阅TWiStErRob的评论 。

 Glide.with(this).load(URL).transform(new CircleTransform(context)).into(imageView); public static class CircleTransform extends BitmapTransformation { public CircleTransform(Context context) { super(context); } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool, toTransform); } private static Bitmap circleCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; // TODO this could be acquired from the pool too Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); Paint paint = new Paint(); paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return result; } @Override public String getId() { return getClass().getName(); } } 

试试这个方法

 Glide.with(this) .load(R.drawable.thumbnail) .bitmapTransform(new CropCircleTransformation(this)) .into(mProfile); 

XML

 <ImageView android:id="@+id/img_profile" android:layout_width="76dp" android:layout_height="76dp" android:background="@drawable/all_circle_white_bg" android:padding="1dp"/> 

all_circle_white_bg.xml

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="oval"> <solid android:color="@android:color/white"/> </shape> </item> </selector> 

其非常简单,我已经看到Glide图书馆非常好的图书馆和散文谷歌图书馆的散文基地

使用该库来进行圆形图像视图

https://github.com/hdodenhof/CircleImageView

现在

//对于一个简单的视图:

  @Override public void onCreate(Bundle savedInstanceState) { ... CircleImageView civProfilePic = (CircleImageView)findViewById(R.id.ivProfile); Glide.load("http://goo.gl/h8qOq7").into(civProfilePic); } 

//有关清单:

 @Override public View getView(int position, View recycled, ViewGroup container) { final ImageView myImageView; if (recycled == null) { myImageView = (CircleImageView) inflater.inflate(R.layout.my_image_view, container, false); } else { myImageView = (CircleImageView) recycled; } String url = myUrls.get(position); Glide.load(url) .centerCrop() .placeholder(R.drawable.loading_spinner) .animate(R.anim.fade_in) .into(myImageView); return myImageView; } 

和XML

 <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/ivProfile android:layout_width="160dp" android:layout_height="160dp" android:layout_centerInParent="true" android:src="@drawable/hugh" app:border_width="2dp" app:border_color="@color/dark" /> 

其他解决scheme不适合我。 我发现他们都有明显的缺点:

  • 使用滑翔转换的解决scheme不能用于占位符
  • 使用圆形图像视图的解决scheme不适用于animation(即交叉淡入淡出)
  • 使用父母的通用方法来解决孩子的问题(例如这里接受的答案)不能很好地解决问题

这是非常有趣的,经过摸索,我find了关于圆angular和圆的Fresco图书馆页面 ,他们列出了基本上相同的限制,并以声明结束:

Android上的四舍五入没有很好的解决scheme,人们必须在上述权衡之间进行select

令人难以置信的是,目前我们还没有真正的解决scheme。 我有一个替代解决scheme基于我上面的链接。 这种方法的缺点是它假定你的背景是纯色(angular落不是真的透明)。 你会这样使用它:

 <RoundedCornerLayout ...> <ImageView ...> </RoundedCornerLayout> 

要点在这里和完整的代码在这里:

 public class RoundedCornerLayout extends RelativeLayout { private Bitmap maskBitmap; private Paint paint; private float cornerRadius; public RoundedCornerLayout(Context context) { super(context); init(context, null, 0); } public RoundedCornerLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0); } public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs, defStyle); } private void init(Context context, AttributeSet attrs, int defStyle) { paint = new Paint(Paint.ANTI_ALIAS_FLAG); setWillNotDraw(false); } @Override public void draw(Canvas canvas) { super.draw(canvas); if (maskBitmap == null) { // This corner radius assumes the image width == height and you want it to be circular // Otherwise, customize the radius as needed cornerRadius = canvas.getWidth() / 2; maskBitmap = createMask(canvas.getWidth(), canvas.getHeight()); } canvas.drawBitmap(maskBitmap, 0f, 0f, paint); } private Bitmap createMask(int width, int height) { Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(mask); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.WHITE); // TODO set your background color as needed canvas.drawRect(0, 0, width, height, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint); return mask; } } 

最简单的方法(需要Glide 4.xx)

 Glide.with(context).load(uri).apply(RequestOptions().circleCrop()).into(imageView) 

使用这个转换,它会正常工作。

 public class CircleTransform extends BitmapTransformation { public CircleTransform(Context context) { super(context); } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool, toTransform); } private static Bitmap circleCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; int borderColor = ColorUtils.setAlphaComponent(Color.WHITE, 0xFF); int borderRadius = 3; int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; // TODO this could be acquired from the pool too Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); if (squared != source) { source.recycle(); } Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); Paint paint = new Paint(); paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); // Prepare the background Paint paintBg = new Paint(); paintBg.setColor(borderColor); paintBg.setAntiAlias(true); // Draw the background circle canvas.drawCircle(r, r, r, paintBg); // Draw the image smaller than the background so a little border will be seen canvas.drawCircle(r, r, r - borderRadius, paint); squared.recycle(); return result; } @Override public String getId() { return getClass().getName(); }} 

我发现了一个简单而又简单的解决scheme,可以在imageview上添加边框,在这种方法中,颜色需要在图像上设置或添加渐变。

脚步:

  1. 采取一个框架布局,并添加两个图像。您可以根据您的要求设置大小。 imgPlaceHolder ,你需要一个白色的图像或颜色,你想设置。
  <ImageView android:id="@+id/imgPlaceHolder" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:src="@drawable/white_bg"/> <ImageView android:id="@+id/imgPic" android:layout_width="190dp" android:layout_height="190dp" android:layout_gravity="center" android:src="@drawable/image01"/> </FrameLayout> 
  1. 将这段代码放在xml文件中后,放在java文件的下面一行。

     Glide.with(this).load(R.drawable.image01).asBitmap().centerCrop().into(new BitmapImageViewTarget(imgPic) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), resource); circularBitmapDrawable.setCircular(true); imageView.setImageDrawable(circularBitmapDrawable); } }); Glide.with(this).load(R.drawable.white_bg).asBitmap().centerCrop().into(new BitmapImageViewTarget(imgPlaceHolder) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), resource); circularBitmapDrawable.setCircular(true); imgTemp2.setImageDrawable(circularBitmapDrawable); } }); 

这将使imageview的边框只是没有任何额外的填充和边距。

:白色图像是强制性的边界,否则将无法正常工作。

快乐编码:)

我之前正在寻找它,而且我以最简单的方式做到了这一点,我希望你会喜欢这个。

  //crete this method into your Utils class and call this method wherever you want to use. //you can set these placeHolder() and error() image static as well. I made it as comment inside this method, then no need to use [placeHolderUrl and errorImageUrl] parameters. remove it from this method. public static void loadImage(final Activity context, ImageView imageView, String url, int placeHolderUrl, int errorImageUrl) { if (context == null || context.isDestroyed()) return; //placeHolderUrl=R.drawable.ic_user; //errorImageUrl=R.drawable.ic_error; Glide.with(context) //passing context .load(getFullUrl(url)) //passing your url to load image. .placeholder(placeHolderUrl) //this would be your default image (like default profile or logo etc). it would be loaded at initial time and it will replace with your loaded image once glide successfully load image using url. .error(errorImageUrl)//in case of any glide exception or not able to download then this image will be appear . if you won't mention this error() then nothing to worry placeHolder image would be remain as it is. .diskCacheStrategy(DiskCacheStrategy.ALL) //using to load into cache then second time it will load fast. .transform(new CircleTransform(context))//this CircleTransform class help to crop an image as circle. .animate(R.anim.fade_in) // when image (url) will be loaded by glide then this face in animation help to replace url image in the place of placeHolder (default) image. .fitCenter()//this method help to fit image into center of your ImageView .into(imageView); //pass imageView reference to appear the image. } 

CircleTransform.java

  public class CircleTransform extends BitmapTransformation { public CircleTransform(Context context) { super(context); if(context==null) return; } private static Bitmap circleCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); Paint paint = new Paint(); paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return result; } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool, toTransform); } @Override public String getId() { return getClass().getName(); } } 

fade_in.xml淡入animation。

  <set xmlns:android="http://schemas.android.com/apk/res/android"> <!--THIS ANIMATION IS USING FOR FADE IN --> <alpha android:duration="800" android:fromAlpha="0.0" android:interpolator="@android:anim/decelerate_interpolator" android:toAlpha="1.0" /> 

最后调用这个方法。

 Utils.loadImage(YourClassName.this,mImageView,url,R.drawable.ic_user,R.drawable.ic_error); 

您可以简单地调用RoundedCornersTransformation构造函数,它具有cornerType枚举input。 喜欢这个:

 Glide.with(context) .load(bizList.get(position).getCover()) .bitmapTransform(new RoundedCornersTransformation(context,20,0, RoundedCornersTransformation.CornerType.TOP)) .into(holder.bizCellCoverImg); 

但首先你必须添加Glide Transformations到你的项目。

这里是一个更模块化和更清洁的方式来圈选Glide中的位图:

  1. 通过扩展BitmapTransformation创build一个自定义转换,然后覆盖像这样的transform方法:

对于Glide 4.xx

 public class CircularTransformation extends BitmapTransformation { @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(null, toTransform); circularBitmapDrawable.setCircular(true); Bitmap bitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); circularBitmapDrawable.setBounds(0, 0, outWidth, outHeight); circularBitmapDrawable.draw(canvas); return bitmap; } @Override public void updateDiskCacheKey(MessageDigest messageDigest) {} } 

对于Glide 3.xx

 public class CircularTransformation extends BitmapTransformation { @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(null, toTransform); circularBitmapDrawable.setCircular(true); Bitmap bitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); circularBitmapDrawable.setBounds(0, 0, outWidth, outHeight); circularBitmapDrawable.draw(canvas); return bitmap; } @Override public String getId() { // Return some id that uniquely identifies your transformation. return "CircularTransformation"; } } 
  1. 然后将其设置在您需要的Glide构build器中:
 Glide.with(yourActivity) .load(yourUrl) .asBitmap() .transform(new CircularTransformation()) .into(yourView); 

希望这可以帮助 :)

glid libary你可以使用这个代码

  Glide.with(context) .load(imageUrl) .asBitmap() .placeholder(R.drawable.user_pic) .centerCrop() .into(new BitmapImageViewTarget(img_profPic) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource); circularBitmapDrawable.setCircular(true); img_profPic.setImageDrawable(circularBitmapDrawable); } }); 

您必须使用CircularImageView来显示该types的图像…

您正在使用Glide库 ,用于加载图像..

在您的项目中创build一个ClassFile并将其加载到Imageview中…并且您将得到Desired Result …

尝试下面的代码…

XML

  <com.yourpackage.CircularImageView android:id="@+id/imageview" android:layout_width="96dp" android:layout_height="96dp" app:border="true" app:border_width="3dp" app:border_color="@color/white" android:src="@drawable/image" /> 

CircularImageView.java

 public class CircularImageView extends ImageView { private int borderWidth; private int canvasSize; private Bitmap image; private Paint paint; private Paint paintBorder; public CircularImageView(final Context context) { this(context, null); } public CircularImageView(Context context, AttributeSet attrs) { this(context, attrs, R.attr.circularImageViewStyle); } public CircularImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // init paint paint = new Paint(); paint.setAntiAlias(true); paintBorder = new Paint(); paintBorder.setAntiAlias(true); // load the styled attributes and set their properties TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0); if(attributes.getBoolean(R.styleable.CircularImageView_border, true)) { int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f); setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize)); setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE)); } if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false)) addShadow(); } public void setBorderWidth(int borderWidth) { this.borderWidth = borderWidth; this.requestLayout(); this.invalidate(); } public void setBorderColor(int borderColor) { if (paintBorder != null) paintBorder.setColor(borderColor); this.invalidate(); } public void addShadow() { setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK); } @Override public void onDraw(Canvas canvas) { // load the bitmap image = drawableToBitmap(getDrawable()); // init shader if (image != null) { canvasSize = canvas.getWidth(); if(canvas.getHeight()<canvasSize) canvasSize = canvas.getHeight(); BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); paint.setShader(shader); // circleCenter is the x or y of the view's center // radius is the radius in pixels of the cirle to be drawn // paint contains the shader that will texture the shape int circleCenter = (canvasSize - (borderWidth * 2)) / 2; canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder); canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(widthMeasureSpec); int height = measureHeight(heightMeasureSpec); setMeasuredDimension(width, height); } private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // The parent has determined an exact size for the child. result = specSize; } else if (specMode == MeasureSpec.AT_MOST) { // The child can be as large as it wants up to the specified size. result = specSize; } else { // The parent has not imposed any constraint on the child. result = canvasSize; } return result; } private int measureHeight(int measureSpecHeight) { int result = 0; int specMode = MeasureSpec.getMode(measureSpecHeight); int specSize = MeasureSpec.getSize(measureSpecHeight); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else if (specMode == MeasureSpec.AT_MOST) { // The child can be as large as it wants up to the specified size. result = specSize; } else { // Measure the text (beware: ascent is a negative number) result = canvasSize; } return (result + 2); } public Bitmap drawableToBitmap(Drawable drawable) { if (drawable == null) { return null; } else if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } 

注意 :

您可以使用

 CircularImageView imgIcon = (CircularImageView)findViewById(R.id.imageview); 

要么

 ImageView imgIcon = (ImageView)findViewById(R.id.imageview); 

它不会影响你的其他图书馆…不必改变你的代码下载图像或其他任何东西…它可以简单地使用XML定义..