欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

让Glide输出指定位置的圆角图片

程序员文章站 2022-07-14 23:48:47
...

使用过Glide的应该都知道,Glide可以通过自定义Transformation来修改最终显示的Bitmap,今天要实现的效果如下图所示:

让Glide输出指定位置的圆角图片

可以看到,整个效果的四个顶角都是圆角的,这个界面其实就是一个ImageView和一个TextView,布局如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:background="@color/colorPrimary">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_margin="50dp"
        android:orientation="vertical">


        <ImageView
            android:id="@+id/iv"
            android:layout_width="match_parent"
            android:layout_height="180dp"
            android:scaleType="centerCrop"
            />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/shape_bg"
            android:gravity="center"
            android:maxLines="2"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:text="描述手机打开了复健科来的实际开始点击开发了考虑到双方均描述手机打开了复健科来的实际开始点击开发了考虑到双方均"
            android:textColor="#333333"
            android:textSize="20sp"
            />

    </LinearLayout>
</FrameLayout>

图片用Glide库加载的,图片上面的2个角设置了圆角,下面的2个角还是直角,文本的则相反,至于文本是怎么实现的呢?其实就是自定义一个shape,然后设置左下角和右下角为圆角,之后作为TextView的背景即可.

来看看shape怎么定义:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners  android:bottomLeftRadius="15dp" android:bottomRightRadius="15dp"/>
    <solid android:color="#ffffff"/>
</shape>

也可以不设置TextView,直接对包裹TextView和ImageView的父容器设置背景,如果这样设置的话,shape就可以4个角设置为圆角,同时需要注意的是shape中的圆角大小要和Glide设置图片的圆角大小一样,这样才可以保证ImageView顶部的圆角和其父View的shape圆角重叠.

对于Glide加载圆角图片,需要自定义一个Transformation,如下所示:

package mchenys.net.csdn.blog.test_clip;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
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;

/**
 * Created by mChenys on 2018/5/11.
 */

public class CornerTransform implements Transformation<Bitmap> {

    private BitmapPool mBitmapPool;

    private float radius;

    private boolean exceptLeftTop, exceptRightTop, exceptLeftBottom, exceptRightBotoom;

    /**
     * 除了那几个角不需要圆角的
     *
     * @param leftTop
     * @param rightTop
     * @param leftBottom
     * @param rightBottom
     */
    public void setExceptCorner(boolean leftTop, boolean rightTop, boolean leftBottom, boolean rightBottom) {
        this.exceptLeftTop = leftTop;
        this.exceptRightTop = rightTop;
        this.exceptLeftBottom = leftBottom;
        this.exceptRightBotoom = rightBottom;
    }

    public CornerTransform(Context context, float radius) {
        this.mBitmapPool = Glide.get(context).getBitmapPool();
        this.radius = radius;
    }

    @Override
    public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
        Bitmap source =  resource.get();
        int finalWidth, finalHeight;
        float ratio; //输出目标的宽高或高宽比例
        if (outWidth > outHeight) { //输出宽度>输出高度,求高宽比
            ratio = (float) outHeight / (float) outWidth;
            finalWidth = source.getWidth();
            finalHeight = (int) ((float) source.getWidth() * ratio); //固定原图宽度,求最终高度
            if (finalHeight > source.getHeight()) { //求出的最终高度>原图高度,求宽高比
                ratio = (float) outWidth / (float) outHeight;
                finalHeight = source.getHeight();
                finalWidth = (int) ((float) source.getHeight() * ratio);//固定原图高度,求最终宽度
            }
        } else if (outWidth < outHeight) { //输出宽度 < 输出高度,求宽高比
            ratio = (float) outWidth / (float) outHeight;
            finalHeight = source.getHeight();
            finalWidth = (int) ((float) source.getHeight() * ratio);//固定原图高度,求最终宽度
            if (finalWidth > source.getWidth()) { //求出的最终宽度 > 原图宽度,求高宽比
                ratio = (float) outHeight / (float) outWidth;
                finalWidth = source.getWidth();
                finalHeight = (int) ((float) source.getWidth() * ratio);
            }
        } else { //输出宽度=输出高度
            finalHeight = source.getHeight();
            finalWidth = finalHeight;
        }

        //修正圆角
        this.radius *= (float) finalHeight / (float) outHeight;
        Bitmap outBitmap = this.mBitmapPool.get(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
        if (outBitmap == null) {
            outBitmap = Bitmap.createBitmap(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(outBitmap);
        Paint paint = new Paint();
        //关联画笔绘制的原图bitmap
        BitmapShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        //计算中心位置,进行偏移
        int width = (source.getWidth() - finalWidth) / 2;
        int height = (source.getHeight() - finalHeight) / 2;
        if (width != 0 || height != 0) {
            Matrix matrix = new Matrix();
            matrix.setTranslate((float) (-width), (float) (-height));
            shader.setLocalMatrix(matrix);
        }

        paint.setShader(shader);
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0.0F, 0.0F, (float) canvas.getWidth(), (float) canvas.getHeight());
        canvas.drawRoundRect(rectF, this.radius, this.radius, paint); //先绘制圆角矩形

        if (exceptLeftTop) { //左上角不为圆角
            canvas.drawRect(0, 0, radius, radius, paint);
        }
        if (exceptRightTop) {//右上角不为圆角
            canvas.drawRect(canvas.getWidth() - radius, 0, radius, radius, paint);
        }

        if (exceptLeftBottom) {//左下角不为圆角
            canvas.drawRect(0, canvas.getHeight() - radius, radius, canvas.getHeight(), paint);
        }

        if (exceptRightBotoom) {//右下角不为圆角
            canvas.drawRect(canvas.getWidth() - radius, canvas.getHeight() - radius, canvas.getWidth(), canvas.getHeight(), paint);
        }

        return BitmapResource.obtain(outBitmap, this.mBitmapPool);
    }


    @Override
    public String getId() {
        return this.getClass().getName();
    }
}

最后是测试类代码:

package mchenys.net.csdn.blog.test_clip;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView imageView = findViewById(R.id.iv);
        String url = "http://pic22.nipic.com/20120727/9880981_174825125145_2.jpg";

        CornerTransform transformation = new CornerTransform(this, dip2px(this, 15));
        //只是绘制左上角和右上角圆角
        transformation.setExceptCorner(false, false, true, true);

        Glide.with(this).
                load(url).
                asBitmap().
                skipMemoryCache(true).
                diskCacheStrategy(DiskCacheStrategy.NONE).
                transform(transformation).
                into(imageView);

    }

    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}