问题
in default, the image that is cropped by glide has no border I need to have a border in the circle image.
回答1:
Version 4
I made this way, RoundedCorners Class:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapResource;
import java.security.MessageDigest;
public class RoundedCornersTransformation implements Transformation<Bitmap> {
public enum CornerType {
ALL,
TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,
TOP, BOTTOM, LEFT, RIGHT,
OTHER_TOP_LEFT, OTHER_TOP_RIGHT, OTHER_BOTTOM_LEFT, OTHER_BOTTOM_RIGHT,
DIAGONAL_FROM_TOP_LEFT, DIAGONAL_FROM_TOP_RIGHT, BORDER
}
private BitmapPool mBitmapPool;
private int mRadius;
private int mDiameter;
private int mMargin;
private CornerType mCornerType;
private String mColor;
private int mBorder;
public RoundedCornersTransformation(Context context, int radius, int margin) {
this(context, radius, margin, CornerType.ALL);
}
public RoundedCornersTransformation(Context context, int radius, int margin, String color, int border) {
this(context, radius, margin, CornerType.BORDER);
mColor = color;
mBorder = border;
}
public RoundedCornersTransformation(BitmapPool pool, int radius, int margin) {
this(pool, radius, margin, CornerType.ALL);
}
public RoundedCornersTransformation(Context context, int radius, int margin,
CornerType cornerType) {
this(Glide.get(context).getBitmapPool(), radius, margin, cornerType);
}
public RoundedCornersTransformation(BitmapPool pool, int radius, int margin,
CornerType cornerType) {
mBitmapPool = pool;
mRadius = radius;
mDiameter = mRadius * 2;
mMargin = margin;
mCornerType = cornerType;
}
@Override
public Resource<Bitmap> transform(Context context, Resource<Bitmap> resource, int outWidth, int outHeight) {
Bitmap source = resource.get();
int width = source.getWidth();
int height = source.getHeight();
Bitmap bitmap = mBitmapPool.get(width, height, Bitmap.Config.ARGB_8888);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
drawRoundRect(canvas, paint, width, height);
return BitmapResource.obtain(bitmap, mBitmapPool);
}
private void drawRoundRect(Canvas canvas, Paint paint, float width, float height) {
float right = width - mMargin;
float bottom = height - mMargin;
switch (mCornerType) {
case ALL:
canvas.drawRoundRect(new RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, paint);
break;
case TOP_LEFT:
drawTopLeftRoundRect(canvas, paint, right, bottom);
break;
case TOP_RIGHT:
drawTopRightRoundRect(canvas, paint, right, bottom);
break;
case BOTTOM_LEFT:
drawBottomLeftRoundRect(canvas, paint, right, bottom);
break;
case BOTTOM_RIGHT:
drawBottomRightRoundRect(canvas, paint, right, bottom);
break;
case TOP:
drawTopRoundRect(canvas, paint, right, bottom);
break;
case BOTTOM:
drawBottomRoundRect(canvas, paint, right, bottom);
break;
case LEFT:
drawLeftRoundRect(canvas, paint, right, bottom);
break;
case RIGHT:
drawRightRoundRect(canvas, paint, right, bottom);
break;
case OTHER_TOP_LEFT:
drawOtherTopLeftRoundRect(canvas, paint, right, bottom);
break;
case OTHER_TOP_RIGHT:
drawOtherTopRightRoundRect(canvas, paint, right, bottom);
break;
case OTHER_BOTTOM_LEFT:
drawOtherBottomLeftRoundRect(canvas, paint, right, bottom);
break;
case OTHER_BOTTOM_RIGHT:
drawOtherBottomRightRoundRect(canvas, paint, right, bottom);
break;
case DIAGONAL_FROM_TOP_LEFT:
drawDiagonalFromTopLeftRoundRect(canvas, paint, right, bottom);
break;
case DIAGONAL_FROM_TOP_RIGHT:
drawDiagonalFromTopRightRoundRect(canvas, paint, right, bottom);
break;
case BORDER:
drawBorder(canvas, paint, right, bottom);
break;
default:
canvas.drawRoundRect(new RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, paint);
break;
}
}
private void drawTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, mMargin + mDiameter),
mRadius, mRadius, paint);
canvas.drawRect(new RectF(mMargin, mMargin + mRadius, mMargin + mRadius, bottom), paint);
canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom), paint);
}
private void drawTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, mMargin + mDiameter), mRadius,
mRadius, paint);
canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom), paint);
canvas.drawRect(new RectF(right - mRadius, mMargin + mRadius, right, bottom), paint);
}
private void drawBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, mMargin + mDiameter, bottom),
mRadius, mRadius, paint);
canvas.drawRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom - mRadius), paint);
canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom), paint);
}
private void drawBottomRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(right - mDiameter, bottom - mDiameter, right, bottom), mRadius,
mRadius, paint);
canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom), paint);
canvas.drawRect(new RectF(right - mRadius, mMargin, right, bottom - mRadius), paint);
}
private void drawTopRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin, mMargin + mRadius, right, bottom), paint);
}
private void drawBottomRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin, mMargin, right, bottom - mRadius), paint);
}
private void drawLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom), paint);
}
private void drawRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom), paint);
}
private void drawOtherTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
paint);
canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom - mRadius), paint);
}
private void drawOtherTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
paint);
canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom - mRadius), paint);
}
private void drawOtherBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
canvas.drawRoundRect(new RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
paint);
canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin, mMargin + mRadius, right - mRadius, bottom), paint);
}
private void drawOtherBottomRightRoundRect(Canvas canvas, Paint paint, float right,
float bottom) {
canvas.drawRoundRect(new RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
paint);
canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
paint);
canvas.drawRect(new RectF(mMargin + mRadius, mMargin + mRadius, right, bottom), paint);
}
private void drawDiagonalFromTopLeftRoundRect(Canvas canvas, Paint paint, float right,
float bottom) {
canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, mMargin + mDiameter),
mRadius, mRadius, paint);
canvas.drawRoundRect(new RectF(right - mDiameter, bottom - mDiameter, right, bottom), mRadius,
mRadius, paint);
canvas.drawRect(new RectF(mMargin, mMargin + mRadius, right - mDiameter, bottom), paint);
canvas.drawRect(new RectF(mMargin + mDiameter, mMargin, right, bottom - mRadius), paint);
}
private void drawDiagonalFromTopRightRoundRect(Canvas canvas, Paint paint, float right,
float bottom) {
canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, mMargin + mDiameter), mRadius,
mRadius, paint);
canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, mMargin + mDiameter, bottom),
mRadius, mRadius, paint);
canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom - mRadius), paint);
canvas.drawRect(new RectF(mMargin + mRadius, mMargin + mRadius, right, bottom), paint);
}
private void drawBorder(Canvas canvas, Paint paint, float right,
float bottom) {
// stroke
Paint strokePaint = new Paint();
strokePaint.setStyle(Paint.Style.STROKE);
if (mColor != null) {
strokePaint.setColor(Color.parseColor(mColor));
} else {
strokePaint.setColor(Color.BLACK);
}
strokePaint.setStrokeWidth(mBorder);
canvas.drawRoundRect(new RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, paint);
// stroke
canvas.drawRoundRect(new RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, strokePaint);
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
}
public String getId() {
return "RoundedTransformation(radius=" + mRadius + ", margin=" + mMargin + ", diameter="
+ mDiameter + ", cornerType=" + mCornerType.name() + ")";
}
}
Now in your Activity, you have to put this:
public static int sCorner = 15;
public static int sMargin = 2;
public static int sBorder = 10;
public static String sColor = "#7D9067";
...
ImageView imageView = (ImageView) findViewById(R.id.activity_main_image_view);
ImageView mImageViewBorder = (ImageView) findViewById(R.id.activity_main_image_view_border);
....
// Rounded corners
Glide.with(this).load("http://scareface.jpeg")
.apply(RequestOptions.bitmapTransform(
new RoundedCornersTransformation(this, sCorner, sMargin))).into(mImageView);
// Rounded corners with border
Glide.with(this).load("http://scareface.jpeg")
.apply(RequestOptions.bitmapTransform(
new RoundedCornersTransformation(this, sCorner, sMargin, sColor, sBorder))).into(mImageViewBorder);
You can check my example in github.
Also you can check this post and this library for Version 3.
回答2:
Drawable for Circle border of ImageView circle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/transparent" />
<stroke
android:width="@dimen/et_thick"
android:color="@color/profile_pic_round" />
<corners android:radius="@dimen/default_corner_radius" />
</shape>
and layout will be like this
Make sure your ImageView height and width lower then RelativeLayout height and width
<RelativeLayout
android:layout_width="150dp"
android:layout_height="150dp"
android:background="@drawable/circle">// set circle drawable here
<ImageView
android:id="@+id/profile_pic"
android:layout_width="145dp"
android:layout_height="145dp"
android:layout_centerInParent="true" />
</RelativeLayout>
and set Image with circuler programetically like this
Glide.with(mContext)
.load(imagePath)//<= path of image
.bitmapTransform(new CropCircleTransform(mContext))//<= For Circuler image
.into(ivProfileImage);//<= your Imageview
回答3:
Based on @wadali's answer to making it work for Glide 4.x and Kotlin programming language. I also optimized the code a little bit, so it is cleaner, you can change the color directly and also leveraging the Kotlin extension function. It's not rounded corner like the accepted answer but fully circle like the sample image below.
Add this code to your project
/**
* Load model into ImageView as a circle image with borderSize (optional) using Glide
*
* @param model - Any object supported by Glide (Uri, File, Bitmap, String, resource id as Int, ByteArray, and Drawable)
* @param borderSize - The border size in pixel
* @param borderColor - The border color
*/
fun <T> ImageView.loadCircularImage(
model: T,
borderSize: Float = 0F,
borderColor: Int = Color.WHITE
) {
Glide.with(context)
.asBitmap()
.load(model)
.apply(RequestOptions.circleCropTransform())
.into(object : BitmapImageViewTarget(this) {
override fun setResource(resource: Bitmap?) {
setImageDrawable(
resource?.run {
RoundedBitmapDrawableFactory.create(
resources,
if (borderSize > 0) {
createBitmapWithBorder(borderSize, borderColor)
} else {
this
}
).apply {
isCircular = true
}
}
)
}
})
}
/**
* Create a new bordered bitmap with the specified borderSize and borderColor
*
* @param borderSize - The border size in pixel
* @param borderColor - The border color
* @return A new bordered bitmap with the specified borderSize and borderColor
*/
fun Bitmap.createBitmapWithBorder(borderSize: Float, borderColor: Int = Color.WHITE): Bitmap {
val borderOffset = (borderSize * 2).toInt()
val halfWidth = width / 2
val halfHeight = height / 2
val circleRadius = Math.min(halfWidth, halfHeight).toFloat()
val newBitmap = Bitmap.createBitmap(
width + borderOffset,
height + borderOffset,
Bitmap.Config.ARGB_8888
)
// Center coordinates of the image
val centerX = halfWidth + borderSize
val centerY = halfHeight + borderSize
val paint = Paint()
val canvas = Canvas(newBitmap).apply {
// Set transparent initial area
drawARGB(0, 0, 0, 0)
}
// Draw the transparent initial area
paint.isAntiAlias = true
paint.style = Paint.Style.FILL
canvas.drawCircle(centerX, centerY, circleRadius, paint)
// Draw the image
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(this, borderSize, borderSize, paint)
// Draw the createBitmapWithBorder
paint.xfermode = null
paint.style = Paint.Style.STROKE
paint.color = borderColor
paint.strokeWidth = borderSize
canvas.drawCircle(centerX, centerY, circleRadius, paint)
return newBitmap
}
And use it
yourImageView.loadCircularImage(
imageUrl, // or any object supported by Glide
borderSizeInPx,
Color.RED // optional, default is white
)
回答4:
Good way to do this thing without using any outer layout
public static <T> void circleImage(final ImageView imageView, T uri, final boolean border) {
Glide.with(imageView.getContext()).load(uri).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(imageView.getContext().getResources(), border ? addWhiteBorder(resource, imageView.getContext()) : resource);
circularBitmapDrawable.setCircular(true);
imageView.setImageDrawable(circularBitmapDrawable);
}
});
}
For Adding border with bitmap
private static Bitmap addBorder(Bitmap resource, Context context) {
int w = resource.getWidth();
int h = resource.getHeight();
int radius = Math.min(h / 2, w / 2);
Bitmap output = Bitmap.createBitmap(w + 8, h + 8, Bitmap.Config.ARGB_8888);
Paint p = new Paint();
p.setAntiAlias(true);
Canvas c = new Canvas(output);
c.drawARGB(0, 0, 0, 0);
p.setStyle(Paint.Style.FILL);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
c.drawBitmap(resource, 4, 4, p);
p.setXfermode(null);
p.setStyle(Paint.Style.STROKE);
p.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
p.setStrokeWidth(3);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
return output;
}
回答5:
It's easy with an outer layout:
your_layout.xml
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="@drawable/round_border_style">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
res/drawable/round_border_style.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient android:angle="0" android:endColor="@color/white" android:startColor="@color/white" android:centerColor="@color/white" android:gradientRadius="10sp" />
<corners android:radius="5dp" />
<stroke android:width="2dp"
android:color="@color/gray"/>
</shape>
</item>
</selector>
Controller.java
GlideApp.with(context).load(url).fitCenter().into(imageView);
来源:https://stackoverflow.com/questions/34037939/how-to-make-border-for-circle-cropped-image-in-glide