Как использовать RoundedBitmapDrawable

Кто-нибудь смог использовать RoundedBitmapDrawable? Исправьте меня, если я ошибаюсь, но, на мой взгляд, он делает круговое изображение из обычного прямоугольного изображения.

То, что я пробовал до сих пор, это

RoundedBitmapDrawable.createRoundedBitmapDrawable(getResources(), BitmapFactory.decodeResource(getResources(), iconResource))

Я попытался добиться: преобразовать любое изображение в круглое изображение и показать его с помощью ImageView.

В случае, если я все перепутал, и все, что я сказал, не имеет смысла. Возможно ли (или проще) сделать это с любой новой структурой? (Android L или новая библиотека поддержки)

Ответ 1

Вам нужно установить радиус угла.

Resources res = getResources();
Bitmap src = BitmapFactory.decodeResource(res, iconResource);
RoundedBitmapDrawable dr =
    RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(Math.max(src.getWidth(), src.getHeight()) / 2.0f);
imageView.setImageDrawable(dr);

Ответ 2

Возможно, это поздний ответ, но я надеюсь, что он будет полезен другим

Если ваше изображение имеет такую ​​же ширину и высоту, вы можете просто установить для setCircular значение true, чтобы получить Rounded Bitmap следующим образом

RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getResources(),your_bitmap);
drawable.setCircular(true);

Ответ 3

Я также нахожу просмотр округленного изображения для эффективности. У меня есть поиск во всей сторонней библиотеке. Я обнаружил, что все они создают новое растровое изображение, которое является утомительной задачей в списке, потребляющей больше памяти.

реферированная библиотека:

из этой библиотеки я использовал

https://github.com/vinc3m1/RoundedImageView

потому что Быстрый ImageView (и Drawable), который поддерживает закругленные углы (и овалы или круги) на основе оригинального примера от Romain Guy

  • не создает копию исходного растрового изображения
  • не использует clipPath, который не является аппаратным ускоренным, а не сглаженным.
  • не использует setXfermode для обрезания растрового изображения и дважды рисует на холсте.

Ответ 4

Я создал класс Utility для создания RoundedBitmapDrawables https://gist.github.com/lawloretienne/a91fb0ce40f083073d4b8939281b3ecb

Он работает для кругов и округлых квадратов.

public class RoundedBitmapDrawableUtility {

    public static RoundedBitmapDrawable getRoundedSquareBitmapDrawable(Context context, Bitmap originalBitmap, int cornerRadius){
        return getRoundedSquareBitmapDrawable(context, originalBitmap, cornerRadius, -1, -1);
    }


    public static RoundedBitmapDrawable getRoundedSquareBitmapDrawable(Context context, Bitmap originalBitmap, int cornerRadius, int borderWidth, int borderColor){
        int originalBitmapWidth = originalBitmap.getWidth();
        int originalBitmapHeight = originalBitmap.getHeight();

        if(borderWidth != -1 && borderColor != -1){
            Canvas canvas = new Canvas(originalBitmap);
            canvas.drawBitmap(originalBitmap, 0, 0, null);

            Paint borderPaint = new Paint();
            borderPaint.setStyle(Paint.Style.STROKE);
            borderPaint.setStrokeWidth(borderWidth);
            borderPaint.setAntiAlias(true);
            borderPaint.setColor(borderColor);

            int roundedRectDelta = (borderWidth/3);
            RectF rectF = new RectF(0 + roundedRectDelta, 0 + roundedRectDelta, originalBitmapWidth - roundedRectDelta, originalBitmapHeight - roundedRectDelta);
            canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, borderPaint);
        }

        RoundedBitmapDrawable roundedImageBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), originalBitmap);
        roundedImageBitmapDrawable.setCornerRadius(cornerRadius);
        roundedImageBitmapDrawable.setAntiAlias(true);
        return roundedImageBitmapDrawable;
    }

    public static RoundedBitmapDrawable getCircleBitmapDrawable(Context context, Bitmap originalBitmap){
        return getCircleBitmapDrawable(context, originalBitmap, -1, -1);
    }

    public static RoundedBitmapDrawable getCircleBitmapDrawable(Context context, Bitmap originalBitmap, int borderWidth, int borderColor){
        if(borderWidth != -1 && borderColor != -1) {
            Canvas canvas = new Canvas(originalBitmap);
            canvas.drawBitmap(originalBitmap, 0, 0, null);

            Paint borderPaint = new Paint();
            borderPaint.setStyle(Paint.Style.STROKE);
            borderPaint.setStrokeWidth(borderWidth);
            borderPaint.setAntiAlias(true);
            borderPaint.setColor(borderColor);

            int circleDelta = (borderWidth / 2) - DisplayUtility.dp2px(context, 1);
            int radius = (canvas.getWidth() / 2) - circleDelta;
            canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, radius, borderPaint);
        }

        RoundedBitmapDrawable roundedImageBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), originalBitmap);
        roundedImageBitmapDrawable.setCircular(true);
        roundedImageBitmapDrawable.setAntiAlias(true);
        return roundedImageBitmapDrawable;
    }
}

Ответ 5

Я хотел бы предложить еще один вариант:

вы можете использовать этот метод, чтобы масштабировать его в соответствии с вашими потребностями и избегать этого исключения:

public static Bitmap scaleBitmapAndKeepRation(Bitmap TargetBmp, int reqHeightInPixels, int reqWidthInPixels) {
        if (TargetBmp != null) {

            if (TargetBmp.getWidth() >= TargetBmp.getHeight()) {

                TargetBmp = Bitmap.createBitmap(
                        TargetBmp,
                        TargetBmp.getWidth() / 2 - TargetBmp.getHeight() / 2,
                        0,
                        TargetBmp.getHeight(),
                        TargetBmp.getHeight()
                );

            } else {

                TargetBmp = Bitmap.createBitmap(
                        TargetBmp,
                        0,
                        TargetBmp.getHeight() / 2 - TargetBmp.getWidth() / 2,
                        TargetBmp.getWidth(),
                        TargetBmp.getWidth()
                );
            }

            if (TargetBmp != null) {
                try {
                    Matrix m = new Matrix();
                    m.setRectToRect(new RectF(0, 0, TargetBmp.getWidth(), TargetBmp.getHeight()), new RectF(0, 0, reqWidthInPixels, reqHeightInPixels), Matrix.ScaleToFit.FILL);
                    Bitmap scaledBitmap = Bitmap.createBitmap(TargetBmp, 0, 0, TargetBmp.getWidth(), TargetBmp.getHeight(), m, true);
                    return scaledBitmap;
                } catch (Exception e) {
                    Log.e("Utils", e.toString());
                    return null;
                }
            }
            return null;
        } else
            return null;
    }

Ответ 6

Текущий способ RoundedBitmapDrawable работает на неквадратных изображениях не так хорошо. Это заставляет контент растягиваться.

Я предлагаю использовать альтернативу для этого, как я написал здесь: Как получить круговой, обрезанный по центру образ, без создания нового растрового изображения?