Android 必知必会 - Glide 加载圆形图片和圆角图片的两种方法

shellqqq 7年前
   <p>两种使用 BitmapTransformation 来实现 Glide 加载圆形图片和圆角图片的方法。</p>    <h2>背景</h2>    <p>Glide 并不能直接支持 Round Pictures ,需要使用 BitmapTransformation 来进行处理。</p>    <p>Round Pictures: CircleImageView / CircularImageView / RoundedImageView are known to have <a href="/misc/goto?guid=4959713459881245067" rel="nofollow,noindex">issues</a> 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.</p>    <p>这里介绍下网上常见的方式和使用 RoundedBitmapDrawable 两种方法,本质上是差不多的:</p>    <ul>     <li>使用 Canvas 和 Paint 来绘制</li>     <li>使用 Android.support.v4.graphics.drawable.RoundedBitmapDrawable</li>    </ul>    <p>PS: RoundedBitmapDrawable 是 support.v4 下的一个类,想了解更多,可以阅读我之前的文章: <a href="/misc/goto?guid=4959713459958914601" rel="nofollow,noindex">Android 必知必会-使用 supportV4 的 RoundedBitmapDrawable 实现圆角</a> 。</p>    <h2>代码实现</h2>    <h3>方法一</h3>    <p>实现圆形图片:</p>    <pre>  <code class="language-java">/**   * Glide 圆形图片 Transform   */    public class GlideCircleTransform extends BitmapTransformation {      public GlideCircleTransform(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;          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();      }  }  </code></pre>    <p>实现圆角图片:</p>    <pre>  <code class="language-java">/**   * Glide 圆角 Transform   */    public class GlideRoundTransform extends BitmapTransformation {        private static float radius = 0f;        /**   * 构造函数 默认圆角半径 4dp   *   * @param context Context   */      public GlideRoundTransform(Context context) {          this(context, 4);      }        /**   * 构造函数   *   * @param context Context   * @param dp 圆角半径   */      public GlideRoundTransform(Context context, int dp) {          super(context);          radius = Resources.getSystem().getDisplayMetrics().density * dp;      }        @Override      protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {          return roundCrop(pool, toTransform);      }        private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {          if (source == null) return null;            Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);          if (result == null) {              result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);          }            Canvas canvas = new Canvas(result);          Paint paint = new Paint();          paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));          paint.setAntiAlias(true);          RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());          canvas.drawRoundRect(rectF, radius, radius, paint);          return result;      }        @Override      public String getId() {          return getClass().getName() + Math.round(radius);      }  }  </code></pre>    <h3>方法二</h3>    <pre>  <code class="language-java">public static Bitmap drawableToBitmap(Drawable drawable) {          // 取 drawable 的长宽          int w = drawable.getIntrinsicWidth();          int h = drawable.getIntrinsicHeight();            // 取 drawable 的颜色格式          Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888                  : Bitmap.Config.RGB_565;          // 建立对应 bitmap          Bitmap bitmap = Bitmap.createBitmap(w, h, config);          // 建立对应 bitmap 的画布          Canvas canvas = new Canvas(bitmap);          drawable.setBounds(0, 0, w, h);          // 把 drawable 内容画到画布中          drawable.draw(canvas);          return bitmap;      }  /**   * RoundedBitmapDrawable 是 V4 下的一个类,不能简单的通过:强制转换成 BitmapDrawable   * Bitmap bitmap = ((BitmapDrawable)xxx).getBitmap();   */  </code></pre>    <p>实现圆形:</p>    <pre>  <code class="language-java">RoundedBitmapDrawable drawableA = RoundedBitmapDrawableFactory.create(getResources(), bitmap);          drawableA.setCircular(true);          Bitmap a = drawableToBitmap(drawableA);  </code></pre>    <p>实现圆角:</p>    <pre>  <code class="language-java">RoundedBitmapDrawable drawableB = RoundedBitmapDrawableFactory.create(getResources(), bitmap);         drawableB.setCornerRadius(30L);         Bitmap b = drawableToBitmap(drawableB);  </code></pre>    <p> </p>    <p>来自:http://likfe.com/2016/08/31/android-glide-roundedBitmapTransformation/</p>    <p> </p>