Android Universal Image Loader 顯示圓角圖片,CenterCrop失效

Android Universal Image Loader是當前使用比較多的圖片加載工具類,可以非常好的“一站式”解決圖片下載、壓縮、存儲、緩存、顯示等問題。並且提供 自定義顯示圖片的接口類BitmapDisplayer,可以自定義圖片展示樣式。


不過,如果你要展示圓角圖片,會發現圖片的scaleType失效了,圖片拉伸失真。


原來,圓角圖片RoundedBitmapDisplayer只能支持centerInside的scaleType,並且該工具類的作者不打算繼續維護了。




我自定義了一個BitmapDisplayer來模擬centerCrop的展示效果。 

思路很簡單,在原始圖片的基礎上,截取圖片中間的部分,創建爲新的bitmap,而後在新的bitmap上畫圓角,然後傳遞給需要展示的imageview。


主要代碼如下

public class RoundedCenterBitmapDisplayer implements BitmapDisplayer {
    protected final int cornerRadius;
    protected final int margin;
    protected final float targetWidthHeightRatio;

    public RoundedCenterBitmapDisplayer(int cornerRadiusPixels, float targetWidthHeightRatio) {
        this(cornerRadiusPixels, 0, targetWidthHeightRatio);
    }

    public RoundedCenterBitmapDisplayer(int cornerRadiusPixels, int marginPixels, float targetWidthHeightRatio) {
        this.cornerRadius = cornerRadiusPixels;
        this.margin = marginPixels;
        this.targetWidthHeightRatio = targetWidthHeightRatio;
    }

    @Override
    public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
        if (!(imageAware instanceof ImageViewAware)) {
            throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected.");
        }

        imageAware.setImageDrawable(new RoundedCenterDrawable(bitmap, cornerRadius, margin, targetWidthHeightRatio));
    }

    public static class RoundedCenterDrawable extends Drawable {

        protected final float cornerRadius;
        protected final int margin;
        protected final float targetWidthHeightRatio;

        protected final RectF mRect = new RectF(),
                mBitmapRect;
        protected final BitmapShader bitmapShader;
        protected final Paint paint;

        public RoundedCenterDrawable(Bitmap bitmap, int cornerRadius, int margin, float targetWidthHeightRatio) {
            this.cornerRadius = cornerRadius;
            this.margin = margin;
            this.targetWidthHeightRatio = targetWidthHeightRatio;

            float bWidth = (float)bitmap.getWidth();
            float bHeight =(float) bitmap.getHeight();
            float ratio = bWidth / bHeight;
            Bitmap targetBitmap = null;
            if (ratio > targetWidthHeightRatio) {
                int height = bitmap.getHeight();
                int width = (int) (height * targetWidthHeightRatio);
                int x = (bitmap.getWidth() - width) / 2;
                int y = 0;
                targetBitmap = bitmap.createBitmap(bitmap, x, y, width, height);
            } else {
                int width = bitmap.getWidth();
                int height = (int) (width / targetWidthHeightRatio);
                int x = 0;
                int y = (bitmap.getHeight() - height) / 2;
                targetBitmap = bitmap.createBitmap(bitmap, x, y, width, height);
            }

            bitmapShader = new BitmapShader(targetBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mBitmapRect = new RectF(margin, margin, targetBitmap.getWidth() - margin, targetBitmap.getHeight() - margin);

            paint = new Paint();
            paint.setAntiAlias(true);
            paint.setShader(bitmapShader);
            paint.setFilterBitmap(true);
            paint.setDither(true);
        }

        @Override
        protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            mRect.set(margin, margin, bounds.width() - margin, bounds.height() - margin);

            // Resize the original bitmap to fit the new bound
            Matrix shaderMatrix = new Matrix();
            shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL);
            bitmapShader.setLocalMatrix(shaderMatrix);

        }

        @Override
        public void draw(Canvas canvas) {
            canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint);
        }

        @Override
        public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
        }

        @Override
        public void setAlpha(int alpha) {
            paint.setAlpha(alpha);
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
            paint.setColorFilter(cf);
        }
    }
}

其中targetWidthHeightRatio是展示圖片的長寬比,通過這個長寬比,來控制圖片的展示區域。

以上。

源碼地址:  點擊打開鏈接




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章