How to round an image with Glide library?

前端 未结 22 1679
悲哀的现实
悲哀的现实 2020-11-28 00:46

So, anybody know how to display an image with rounded corners with Glide? I am loading an image with Glide, but I don\'t know how to pass rounded params to this library.

相关标签:
22条回答
  • 2020-11-28 01:07

    Glide version 4.6.1

    Glide.with(context)
    .load(url)
    .apply(RequestOptions.bitmapTransform(new CircleCrop()))
    .into(imageView);
    
    0 讨论(0)
  • 2020-11-28 01:09

    With glide library you can use this code:

    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);
            }
        });
    
    0 讨论(0)
  • 2020-11-28 01:11

    The other solutions did not work for me. I found they all have significant drawbacks:

    • Solutions using glide transformations do not work with placeholders
    • Solutions using rounded image views do not work with animations (i.e. crossfade)
    • Solutions using a generic method of a parent that clips its children (i.e. the accepted answer here) do not work well with glide

    It is really interesting that after fumbling around with this I found the Fresco library page about rounded corners and circles in which they list basically the same limitations and conclude with the statement:

    there is no really good solution for rounding corners on Android and one has to choose between the aforementioned trade-offs

    Unbelievable that at this time we still dont have a real solution. I have an alternate solution based on the link I put above. The drawback with this approach is that it assumes your background is a solid color (the corners aren't really transparent). You would use it like this:

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

    The gist is here and full code here:

    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;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 01:11

    You have to use CircularImageView to Display that type of Image...

    You are using Glide library which used to load images..

    Create One ClassFile in your Project and Load it in Imageview... and You will get Desired Result...

    Try Following Code...

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

    Note :

    You can use

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

    or

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

    it wont affect your other libraries... dont have to change your code for downloading image or anything else... it simply can be defined using XML too..

    0 讨论(0)
  • 2020-11-28 01:12

    For Glide 4.x.x

    use

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

    from doc it stated that

    Round Pictures: CircleImageView/CircularImageView/RoundedImageView are known to have issues with TransitionDrawable (.crossFade() with .thumbnail() or .placeholder()) and animated GIFs, use a BitmapTransformation (.circleCrop() will be available in v4) or .dontAnimate() to fix the issue

    0 讨论(0)
  • 2020-11-28 01:15

    According to this answer, the easiest way in both languages is:

    Kotlin:

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

    Java:

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

    This works on Glide 4.X.X

    0 讨论(0)
提交回复
热议问题