Как сделать ImageView с закругленными углами?

573

В Android ImageView по умолчанию является прямоугольником. Как сделать прямоугольник с закругленными углами (обрезать все 4 угла моего растрового изображения, чтобы они были прямоугольниками с закругленными углами) в ImageView?

Майкл
источник
Это может быть полезно stackoverflow.com/questions/26850780/…
Mangesh
Ниже, более старые, более сложные ответы, я думаю, должен быть принятым ответом: RoundedBitmapDrawable , добавлено в версии 4 библиотеки поддержки v4.
Jonik
Вы можете сделать это проще всего, просто используя CardView с ImageView внутри - посмотрите пример здесь stackoverflow.com/a/41479670/4516797
Тарас Вовкович,
Эта библиотека очень полезна.
grrigore
Проверьте это сейчас мы должны ShapeableImageViewсделать круглую или закругленную ImageView stackoverflow.com/a/61086632/7666442
Nilesh Rathod

Ответы:

545

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

http://www.ruibm.com/?p=184

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

Конечный код выглядит так:

package com.company.app.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;

public class ImageHelper {
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
}

Надеюсь, это поможет кому-то!

Джордж Уолтерс II
источник
4
Он не работает для всех устройств. Нужно ли где-нибудь менять?
Spring Breaker
7
Это займет около 0,03 секунды, чтобы сделать это для изображения 200 * 200, поэтому я думаю, что это не лучшее решение.
Джеки,
2
Он только округляет верхний левый и верхний правый углы. Почему ?
Prateek
1
Решение @ vinc3m1 здесь github.com/makeramen/RoundedImageView работает очень хорошо! также см. его ответ ( stackoverflow.com/a/15032283/2048266 )
ном
16
Плохо работает при попытке установить тип масштаба изображения, работает только fitXY, centerCrop и другие показывают непредсказуемые результаты, у кого-нибудь здесь есть такие же проблемы?
Шиванш
211

Хотя приведенный выше ответ работает, Romain Guy (основной разработчик для Android) показывает лучший метод в своем блоге, который использует меньше памяти, используя шейдер, не создавая копию растрового изображения. Общая суть функциональности здесь:

BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);

RectF rect = new RectF(0.0f, 0.0f, width, height);

// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, paint);

Преимущество этого перед другими методами состоит в том, что это:

  • не создает отдельную копию растрового изображения, которое использует много памяти с большими изображениями [против большинства других ответов здесь]
  • поддерживает сглаживание [против метода clipPath]
  • поддерживает альфа [vs xfermode + метод porterduff]
  • поддерживает аппаратное ускорение [против метода clipPath]
  • рисует только один раз на холст [методы xfermode и clippath]

Я создал RoundedImageView на основе этого кода, который оборачивает эту логику в ImageView и добавляет надлежащую ScaleTypeподдержку и необязательную закругленную границу.

vinc3m1
источник
в вашем / example / res / layout / rounded_item.xml почему вы указываете SRC изображения , когда все ваши источники жёстко? Хорошая демка, просто излишняя.
Кто-то где-то
у вашего сэмпла серьезная проблема нехватки памяти, как и у оригинального образца Romain Guy. Я до сих пор не знаю, что вызывает это, но, как и его код, это действительно трудно найти. Если вы не видите сбой в приложении из-за OOM, вы можете поворачивать приложение несколько раз, пока оно не произойдет (зависит от вашего устройства, ПЗУ и т. Д.). Я уже писал об этом здесь: stackoverflow.com/questions/14109187/…
разработчик Android
1
Никто другой не сообщает о проблеме нехватки памяти, так что это должно быть что-то, что вы делаете за пределами кода, который является неправильным. В примере правильно хранится ограниченный набор растровых изображений в адаптере, и они не воссоздаются при каждом отображении представления. Показанный здесь пример представляет собой фрагмент метода draw () в Drawable, который использует ссылку на исходное растровое изображение, которое он содержит, и работает правильно. Он не предназначен для изменения исходного растрового изображения, а только для визуализации его с закругленными углами. Центр урожая отлично работает в этом примере.
vinc3m1
1
Если вы можете предоставить скриншоты или устройства там, где они не работают, или даже предложить запрос исправления и извлечения, это будет наиболее продуктивным. Я тестировал вращение несколько раз на моих устройствах, и память осталась прежней.
vinc3m1
11
Обратите внимание, что он не будет работать, если размер изображения превышает 2048 пикселей. Шейдер не поддерживает текстуру, которая будет больше этой.
Габор
209

Другой простой способ - использовать CardView с угловым радиусом и ImageView внутри:

  <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:cardCornerRadius="8dp"
            android:layout_margin="5dp"
            android:elevation="10dp">

            <ImageView
                android:id="@+id/roundedImageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/image"
                android:background="@color/white"
                android:scaleType="centerCrop"
                />
        </android.support.v7.widget.CardView>

введите описание изображения здесь

Тарас Вовкович
источник
5
Похоже, хороший обходной путь. Но это не обрезает изображения на предварительных леденцах на палочке.
Николай
1
Что если нам нужен радиус только в верхнем левом и верхнем правом углах, а не во всех углах?
Пратик
3
Очень простой и умный способ применить кривую границу в любом представлении.
АМИ ЧАРАДАВА
1
Хорошее решение, но высота поддерживается только на уровне API 21 и выше
Саад Билал
1
Чтобы отключить повышение уровня карты, используйте приложение: cardElevation = "0dp" (не android: повышение)
Johnny Five
150

Обрезание к округлым формам было добавлено в Viewкласс в API 21.

Просто сделай это:

  • Создайте рисованную закругленную форму, примерно так:

Рез / рисуем / round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>
  • Установите рисование в качестве фона вашего ImageView: android:background="@drawable/round_outline"
  • Согласно этой документации , все, что вам нужно сделать, это добавитьandroid:clipToOutline="true"

К сожалению, есть ошибка, и этот атрибут XML не распознается. К счастью, мы все еще можем настроить отсечение в Java:

  • В вашей деятельности или фрагменте: ImageView.setClipToOutline(true)

Вот как это будет выглядеть:

введите описание изображения здесь

Замечания:

Этот метод работает для любой нарисованной формы (не только округленной). Он будет обрезать ImageView к любой форме фигуры, которую вы определили в Drawable XML.

Специальное примечание о ImageViews

setClipToOutline()работает только в том случае, если фон представления установлен на форму для рисования. Если эта фоновая фигура существует, View рассматривает контур фигуры как границы для целей отсечения и затенения.

Это означает, что если вы хотите использовать setClipToOutline()для скругления углов в ImageView, ваше изображение должно быть установлено с использованием android:srcвместо android:background(поскольку фон должен быть установлен на вашу округлую форму). Если вы ДОЛЖНЫ использовать background для установки изображения вместо src, вы можете использовать этот обходной путь:

  • Создайте макет и установите его фон в соответствии с вашей формой.
  • Оберните этот макет вокруг вашего ImageView (без заполнения)
  • ImageView (включая все остальное в макете) теперь будет отображаться с округлой формой макета.
hungryghost
источник
10
Ошибка: (x) Не найден идентификатор ресурса для атрибута «clipToOutline» в пакете «android»
Anu Martin
7
Вместо этого android:clipToOutlineнужно использовать android:outlineProvider="background".
WindRider
2
Еще одна причина, по которой я так сильно "люблю" Google, заключается в том, что этот баг почти моего возраста и все еще живет в его маленьком мире. Google, кажется, не дает об этом *)
Фарид
1
Мне кажется, что этот метод не имеет успеха, когда я устанавливаю только угол topleft и topRight в форме фона на закругленный.
Peterdk
@AnuMartin, это известная проблема - issetracker.google.com/issues/37036728
Вадим Котов
132

В версии 21 библиотеки поддержки теперь есть решение этой проблемы: оно называется RoundedBitmapDrawable .

По сути, это как обычный Drawable, за исключением того, что вы задаете ему угловой радиус для отсечения с помощью:

setCornerRadius(float cornerRadius)

Итак, начиная с Bitmap srcцели ImageView, это будет выглядеть примерно так:

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
tyczj
источник
3
Большое спасибо, вот следующий шаг: stackoverflow.com/questions/24878740/…
David d C e Freitas
на самом деле есть android.support.v4.graphics.drawable.RoundedBitmapDrawableFactoryтак v4и поддерживает его.
Deadfish
2
@deadfish да, он есть в v4библиотеке поддержки, но не до REVISION 21библиотеки поддержки
tyczj
3
Это простое и актуальное решение. Это требует наименьшего количества кода и обладает большой расширяемостью. Может работать с изображениями из локального файла, с кэшированным рисунком или даже с сетевым изображением Volley. Я полностью согласен, что это должен быть принятый ответ в настоящее время, как отметил @Jonik.
Katie
2
К сожалению, не работает scaleType centerCrop(поддержка библиотеки v25.3.1)
Rocknow
67

Я сделал Custom ImageView:

public class RoundRectCornerImageView extends ImageView {

    private float radius = 18.0f;
    private Path path;
    private RectF rect;

    public RoundRectCornerImageView(Context context) {
        super(context);
        init();
    }

    public RoundRectCornerImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RoundRectCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        path = new Path();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        path.addRoundRect(rect, radius, radius, Path.Direction.CW);
        canvas.clipPath(path);
        super.onDraw(canvas);
    }
}

Как пользоваться:

<com.mypackage.RoundRectCornerImageView
     android:id="@+id/imageView"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/image"
     android:scaleType="fitXY" />

Вывод:

введите описание изображения здесь

Надеюсь, это поможет вам.

Хирен Патель
источник
это делает изображение размытым
Амит Худа
2
работает даже с android: scaleType = "centerCrop", просто, не создает нового растрового изображения. Спасибо!
ernazm
1
@Hiren Это решение отлично работает для ImageView с фоновым изображением. Но это не работает для ImageViews, у которых есть только цвет фона и нет изображения. Подскажите, пожалуйста, почему это происходит?
user2991413
Canvas.clipPath()может вызвать java.lang.UnsupportedOperationExceptionв некоторых случаях. См. Stackoverflow.com/questions/13248904/…
Артём
1
Это решение работает только для изображений, установленных android:background, но не android:src.
CoolMind
65

Быстрое решение XML -

<android.support.v7.widget.CardView
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:cardElevation="0dp"
            app:cardCornerRadius="4dp">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rounded_user_image"
        android:scaleType="fitXY"/>

</android.support.v7.widget.CardView>

Вы можете установить желаемую ширину, высоту и радиус в CardView и scaleType в ImageView.

С AndroidX используйте <androidx.cardview.widget.CardView>

Чираг Миттал
источник
4
этот подход работал в моем случае с androidx.cardview.widget.CardView
Иван
7
Не уверен, почему это не имеет больше голосов? На мой взгляд, лучшее решение без библиотек и множества дерьмового кода (хотя я использовал масштабирование centerCrop в моем случае).
ThemBones
1
Пока не так много голосов, потому что это новый ответ. Но я положил +1, чтобы переместить его в ближайшее время! Спасибо!
Micer
однако, он работает , но здесь изображение будет растягиваться из - за scaleType="fitXY"и не выглядит надлежащего @ThemBones
МАСТЕРА
@WIZARD, поэтому я упомянул, что вы можете установить желаемый scaleType в ImageView
Чираг Миттал
57

Я обнаружил, что оба метода были очень полезны при разработке рабочего решения. Вот моя составная версия, которая не зависит от пикселей и позволяет вам иметь некоторые квадратные углы с остальными углами, имеющими одинаковый радиус (что является обычным вариантом использования). Благодаря обоим решениям выше:

public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR  ) {

    Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    final float densityMultiplier = context.getResources().getDisplayMetrics().density;

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, w, h);
    final RectF rectF = new RectF(rect);

    //make sure that our rounded corner is scaled appropriately
    final float roundPx = pixels*densityMultiplier;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);


    //draw rectangles over the corners we want to be square
    if (squareTL ){
        canvas.drawRect(0, h/2, w/2, h, paint);
    }
    if (squareTR ){
        canvas.drawRect(w/2, h/2, w, h, paint);
    }
    if (squareBL ){
        canvas.drawRect(0, 0, w/2, h/2, paint);
    }
    if (squareBR ){
        canvas.drawRect(w/2, 0, w, h/2, paint);
    }


    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(input, 0,0, paint);

    return output;
}

Кроме того, я переопределил ImageView, чтобы вставить это, чтобы я мог определить его в XML. Возможно, вы захотите добавить некоторую логику, которую здесь делает супер-вызов, но я прокомментировал это, поскольку в моем случае это бесполезно.

    @Override
protected void onDraw(Canvas canvas) {
    //super.onDraw(canvas);
        Drawable drawable = getDrawable();

        Bitmap b =  ((BitmapDrawable)drawable).getBitmap() ;
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

        int w = getWidth(), h = getHeight();


        Bitmap roundBitmap =  CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false);
        canvas.drawBitmap(roundBitmap, 0,0 , null);
}

Надеюсь это поможет!

Каспар Хармер
источник
4
довольно круто, особенно расширяя ImageView
Someone Somewhere
2
Простой способ сохранить логику ImageView # onDraw () состоит в том, чтобы установить растровое изображение с закругленными углами для рисования ImageView и оставить super.onDraw () для рисования растрового изображения. Я создал класс RoundedCornerImageView , и его пример использования здесь . Обратите внимание, что используемый мной метод getRoundedCornerBitmap () не зависит от пикселей.
умбалаконмеогия
Спасибо за RoundedCornerImageView. Я использовал его, но изменил, чтобы он не зависел от плотности пикселей.
PacificSky
Исходный код RoundedCornerImageView от umba находится здесь: code.google.com/p/android-batsg/source/browse/trunk/…
Someone Somewhere
@Caspar Harmer работает хорошо, всего 1 правка ... есть четыре условия .. просто измените их, как если бы я установил true, true, false, false, он установит нижний угол вместо верхнего угла .. в противном случае код работает нормально.so squareTL и squareTR - это условия для squareBL и squareBR соответственно ... и наоборот.
TheFlash
48

Округлое изображение Использование ImageLoader здесь

Создать DisplayImageOptions:

DisplayImageOptions options = new DisplayImageOptions.Builder()
    // this will make circle, pass the width of image 
    .displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu))) 
    .cacheOnDisc(true)
    .build();

imageLoader.displayImage(url_for_image,ImageView,options);

Или вы можете использовать Picassoбиблиотеку с площади.

Picasso.with(mContext)
    .load(com.app.utility.Constants.BASE_URL+b.image)
    .placeholder(R.drawable.profile)
    .error(R.drawable.profile)
    .transform(new RoundedTransformation(50, 4))
    .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
    .centerCrop()
    .into(v.im_user);

Вы можете скачать файл RoundedTransformation здесь здесь

Shailesh
источник
1
Не отображается изображение
Амит Тэпер
3
Библиотека Пикассо одна хорошая, и ее очень легко реализовать, спасибо большое +1
Hitesh
3
Библиотека Picasso, по-видимому, не преобразует изображение «заполнитель» и «ошибка», поэтому, если ваше изображение не загружается (ошибка) или занимает начальную загрузку (заполнитель), оно не будет отображать изображение в виде округленного изображения. github.com/square/picasso/issues/337
Pelpotronic
Другие полезные преобразования Пикассо предоставлены этой библиотекой, которая также содержит RoundedCornersTransformation: github.com/wasabeef/picasso-transformations
Massimo
Не работает с обрезкой изображений в Univ. Загрузчик изображений.
Яр
26

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

Создайте граничную форму с прозрачным содержимым следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners 
        android:radius="30dp" />
    <stroke 
        android:color="#ffffffff"
        android:width="10dp" />
</shape> 

Затем в RelativeLayout вы можете сначала разместить свое изображение, а затем в том же месте над формой с другим ImageView. Форма покрытия должна быть больше по размеру на величину ширины границы. Будьте осторожны, чтобы взять больший угловой радиус, поскольку внешний радиус определен, но внутренний радиус - это то, что покрывает ваше изображение.

Надеюсь, это тоже кому-нибудь поможет.

Отредактируйте согласно запросу CQM пример относительного макета:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageToShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imgCorners"
        android:layout_alignLeft="@+id/imgCorners"
        android:layout_alignRight="@+id/imgCorners"
        android:layout_alignTop="@+id/imgCorners"
        android:background="#ffffff"
        android:contentDescription="@string/desc"
        android:padding="5dp"
        android:scaleType="centerCrop" />

    <ImageView
        android:id="@+id/imgCorners"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/desc"
        android:src="@drawable/corners_white" />

</RelativeLayout>
Кристиан
источник
Можете ли вы подробнее рассказать об этом с помощью большего количества кода, особенно о том, что делается со вторым представлением изображения и где применяется XML «Border shape» (как src или как фон?), несколько вопросов здесь. Мне нравится это решение, так как оно позволит мне независимо контролировать все четыре угла
CQM
1
Хотя кажется, что это простой ответ, он, к сожалению, добавляет поле вокруг «маскированного» изображения, что является нежелательным побочным эффектом.
Абдалрахман Шату
да, но то же самое работает с ImageView на основе PNG-Drawable с закругленными углами и прозрачным фоном или 9-Patch-Drawable, если у вас есть неопределенный аспект.
Кристиан
Я делаю то же самое, и это работает; просто хотите узнать, не создаст ли это никаких проблем с ориентацией и разным размером телефона?
открыто и бесплатно
Если вы сохраняете размеры относительно друг друга, это не должно создавать проблем.
Кристиан
22

Начиная с версии 1.2.0-alpha03этого на компоненты материала библиотеки есть новыйShapeableImageView .

Вы можете использовать что-то вроде:

  <com.google.android.material.imageview.ShapeableImageView
      ...
      app:shapeAppearanceOverlay="@style/roundedImageView"
      app:srcCompat="@drawable/ic_image" />

с:

  <style name="roundedImageView" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">8dp</item>
  </style>

Или программно:

float radius = getResources().getDimension(R.dimen.default_corner_radius);
imageView.setShapeAppearanceModel(imageView.getShapeAppearanceModel()
    .toBuilder()
    .setAllCorners(CornerFamily.ROUNDED,radius)
    .build());

введите описание изображения здесь

Габриэле Мариотти
источник
Если изображение имеет цвет фона, в настоящее время он создает фоновый цвет для скругления углов. Это также игнорирует свойство scaleType для изображения.
Inokey
14

Моя реализация ImageView с виджетом закругленных углов, который (вниз || вверх) размеры изображения до требуемых размеров. Используется кодовая форма CaspNZ.

public class ImageViewRounded extends ImageView {

    public ImageViewRounded(Context context) {
        super(context);
    }

    public ImageViewRounded(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        BitmapDrawable drawable = (BitmapDrawable) getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return; 
        }

        Bitmap fullSizeBitmap = drawable.getBitmap();

        int scaledWidth = getMeasuredWidth();
        int scaledHeight = getMeasuredHeight();

        Bitmap mScaledBitmap;
        if (scaledWidth == fullSizeBitmap.getWidth() && scaledHeight == fullSizeBitmap.getHeight()) {
            mScaledBitmap = fullSizeBitmap;
        } else {
            mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap, scaledWidth, scaledHeight, true /* filter */);
        }

        Bitmap roundBitmap = ImageUtilities.getRoundedCornerBitmap(getContext(), mScaledBitmap, 5, scaledWidth, scaledHeight,
                false, false, false, false);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

}
Damjan
источник
12
Откуда берется ImageUtilities?
JasonWyatt
1
@JasonWyatt см sorrodos пост ниже
Damjan
12

В последнее время есть другой способ - использование Glide Generated API . Это требует некоторой начальной работы, но затем дает вам всю мощь Glide с гибкостью, позволяющей делать что угодно, потому что вы записываете реальный код, поэтому я думаю, что это хорошее решение для долгосрочной перспективе. Кроме того, использование очень просто и аккуратно.

Сначала настройте Glide версии 4+:

implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'

Затем создайте класс модуля приложения Glid для запуска обработки аннотаций:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

Затем создайте расширение Glide, которое действительно работает. Вы можете настроить его, чтобы сделать все, что вы хотите:

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {}

    @NonNull
    @GlideOption
    public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) {
        int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return options.transforms(new RoundedCorners(px));
    }
}

После добавления этих файлов создайте свой проект.

Затем используйте его в своем коде так:

GlideApp.with(this)
        .load(imageUrl)
        .roundedCorners(getApplicationContext(), 5)
        .into(imageView);
Сэр кодесалот
источник
Не забудьте добавить пробел между RequestOptionsи optionsв параметрах
StevenTB
Выполнено. Спасибо за вклад.
Сэр Codesalot,
.NetCorners не приходят нам нужно что-то еще настроить? Даже после восстановления проекта
доктор АНДРО
Это сработало для меня, спасибо. Я обнаружил, что проще избегать использования @GlideExtensionаннотированного класса, и просто обратился к методу .transform(new RoundedCorners(px))where pxis same ( int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));).
Майкл Ософски
10

Есть классная библиотека, которая позволяет формировать изображения.

Вот пример:

<com.github.siyamed.shapeimageview.mask.PorterShapeImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:siShape="@drawable/shape_rounded_rectangle"
    android:src="@drawable/neo"
    app:siSquare="true"/>

Определение формы:

<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
    <corners
        android:topLeftRadius="18dp"
        android:topRightRadius="18dp"
        android:bottomLeftRadius="18dp"
        android:bottomRightRadius="18dp" />
    <solid android:color="@color/black" />
</shape>

Результат:

результат

grrigore
источник
1
Это здорово и делает гораздо больше, например, вы можете добавить границу и использовать любую форму
Адам Кис
8

Вот простой пример переопределения imageView, вы также можете использовать его в дизайнере макетов для предварительного просмотра.

public class RoundedImageView extends ImageView {

    public RoundedImageView(Context context) {
        super(context);
    }

    public RoundedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        float radius = 0.1f;
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
        rid.setCornerRadius(bitmap.getWidth() * radius);
        super.setImageDrawable(rid);
    }
}

Это для быстрого решения. Радиус используется на всех углах и зависит от процента ширины растрового изображения.

Я только что переопределил setImageDrawableи использовал метод поддержки v4 для округления растрового изображения.

Применение:

<com.example.widgets.RoundedImageView
        android:layout_width="39dp"
        android:layout_height="39dp"
        android:src="@drawable/your_drawable" />

Предварительный просмотр с imageView и пользовательским imageView:

введите описание изображения здесь

мертвая рыба
источник
Это работает в любой ситуации, спасибо. Ты спас мой день.
Мехул Соланки
7

Вы должны расширить ImageViewи нарисовать свой собственный прямоугольник с закругленными углами.

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

[править] Наложите рамку, чтобы использовать оригинальное изображение, FrameLayoutнапример , с помощью . Первым элементом FrameLayoutбудет изображение, которое вы хотите округлить. Затем добавьте еще один ImageViewс рамкой. Второй ImageViewбудет отображаться поверх оригинала, ImageViewи, таким образом, Android будет рисовать его содержимое выше оригинала ImageView.

MrSnowflake
источник
Спасибо. Но есть только метод setDrawable для ImageView, как я могу установитьDrawable ImageView на содержимое моего изображения, а затем наложить закругленную рамку поверх ImageView?
Майкл
Извините, мне было неясно. Я имел в виду накладывая в макете: таким образом (то есть) использовать FrameLayoutПогружает ImageViewв нем и добавить еще ImageViewс закругленной рамой. Таким образом, первая ImageViewбудет отображать выбранную вами фотографию, а вторая ImageFrame- округленную рамку.
MrSnowflake
Правильно - с FrameLayout вы можете наложить одно изображение / представление на другое. Вы также можете использовать тег android: foreground FrameLayout.
Ричард Ле Мезурье
7

Ромэн Гай, где он находится.

Сокращенная версия выглядит следующим образом.

Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();

Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);

imageView.setImageBitmap(bitmapRounded);
Alex
источник
к сожалению, хотя он и работает, но, как и остальные решения здесь, он создает новое растровое изображение вместо использования текущего.
Android-разработчик
на самом деле, нет. bitmapRounded будет использоваться снова и снова. если у вас был доступ к рисуемому холсту, вы можете напрямую использовать метод draw вместо генерации нового растрового изображения.
Алекс
Как ты это делаешь? Предположим, я не использую какой-либо специальный drawable, а обрабатываю только одно растровое изображение и использую setImageBitmap в конце процесса. Как бы я достичь такой вещи?
Android-разработчик
проверить Ромен пример парня curious-creature.org/2012/12/11/... и пример приложения docs.google.com/file/d/0B3dxhm5xm1sia2NfM3VKTXNjUnc/edit
Alex
оба не изменяют растровое изображение, но обертывают его, используя настраиваемый чертеж и настраиваемое изображение. это не то, о чем я спрашивал. Я спросил, как вы можете изменить само растровое изображение.
Android-разработчик
7

Это чистое решение XML было достаточно хорошо в моем случае. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

РЕДАКТИРОВАТЬ

Вот ответ в двух словах:

В папке / res / drawable создайте файл frame.xml. В нем мы определяем простой прямоугольник с закругленными углами и прозрачным центром.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
     <solid android:color="#00ffffff" />
     <padding android:left="6dp"
        android:top="6dp"
        android:right="6dp"
        android:bottom="6dp" />
     <corners android:radius="12dp" />
     <stroke android:width="6dp" android:color="#ffffffff" />
</shape>

В ваш файл макета вы добавляете LinearLayout, который содержит стандартный ImageView, а также вложенный FrameLayout. FrameLayout использует отступы и настраиваемый рисунок, чтобы создать иллюзию закругленных углов.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:gravity="center" 
    android:background="#ffffffff">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="6dp"
        android:src="@drawable/tr"/>

    <FrameLayout 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="6dp"
            android:src="@drawable/tr"/>

        <ImageView 
             android:src="@drawable/frame"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />

    </FrameLayout>

</LinearLayout>
j7nn7k
источник
хорошая идея, я использовал это, чтобы показать неровные углы ImageView
Gal Rom
6

Подсказки к Джорджу Уолтерсу II выше, я просто взял его ответ и немного расширил его, чтобы по-разному поддерживать закругление отдельных углов. Это можно было бы оптимизировать немного дальше (некоторые целевые участки перекрываются), но не намного.

Я знаю, что эта ветка немного устарела, но это один из лучших результатов для запросов в Google о том, как закруглить углы ImageViews на Android.

/**
 * Use this method to scale a bitmap and give it specific rounded corners.
 * @param context Context object used to ascertain display density.
 * @param bitmap The original bitmap that will be scaled and have rounded corners applied to it.
 * @param upperLeft Corner radius for upper left.
 * @param upperRight Corner radius for upper right.
 * @param lowerRight Corner radius for lower right.
 * @param lowerLeft Corner radius for lower left.
 * @param endWidth Width to which to scale original bitmap.
 * @param endHeight Height to which to scale original bitmap.
 * @return Scaled bitmap with rounded corners.
 */
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft,
        float upperRight, float lowerRight, float lowerLeft, int endWidth,
        int endHeight) {
    float densityMultiplier = context.getResources().getDisplayMetrics().density;

    // scale incoming bitmap to appropriate px size given arguments and display dpi
    bitmap = Bitmap.createScaledBitmap(bitmap, 
            Math.round(endWidth * densityMultiplier),
            Math.round(endHeight * densityMultiplier), true);

    // create empty bitmap for drawing
    Bitmap output = Bitmap.createBitmap(
            Math.round(endWidth * densityMultiplier),
            Math.round(endHeight * densityMultiplier), Config.ARGB_8888);

    // get canvas for empty bitmap
    Canvas canvas = new Canvas(output);
    int width = canvas.getWidth();
    int height = canvas.getHeight();

    // scale the rounded corners appropriately given dpi
    upperLeft *= densityMultiplier;
    upperRight *= densityMultiplier;
    lowerRight *= densityMultiplier;
    lowerLeft *= densityMultiplier;

    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(Color.WHITE);

    // fill the canvas with transparency
    canvas.drawARGB(0, 0, 0, 0);

    // draw the rounded corners around the image rect. clockwise, starting in upper left.
    canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint);
    canvas.drawCircle(width - upperRight, upperRight, upperRight, paint);
    canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint);
    canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint);

    // fill in all the gaps between circles. clockwise, starting at top.
    RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2);
    RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight);
    RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height);
    RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft);

    canvas.drawRect(rectT, paint);
    canvas.drawRect(rectR, paint);
    canvas.drawRect(rectB, paint);
    canvas.drawRect(rectL, paint);

    // set up the rect for the image
    Rect imageRect = new Rect(0, 0, width, height);

    // set up paint object such that it only paints on Color.WHITE
    paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET));

    // draw resized bitmap onto imageRect in canvas, using paint as configured above
    canvas.drawBitmap(bitmap, imageRect, imageRect, paint);

    return output;
}
sorrodos
источник
+1 за добавление множителя плотности и добавление поддержки для скругления углов по отдельности. Я на самом деле использовал решение сверху, так как ваше решение не совсем работало - но оно было очень полезным! Смотрите мое составное решение ниже:
Каспар Хармер
6

Примените форму, imageViewкак показано ниже:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="#faf5e6" />
    <stroke
        android:width="1dp"
        android:color="#808080" />
    <corners android:radius="15dp" />
    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />
</shape>

это может быть полезно для вашего друга.

Jigar
источник
6

Почему бы не сделать отсечение draw()?

Вот мое решение:

  • Расширить RelativeLayout с отсечкой
  • Поместите ImageView (или другие виды) в макет:

Код:

public class RoundRelativeLayout extends RelativeLayout {

    private final float radius;

    public RoundRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray attrArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundRelativeLayout);
        radius = attrArray.getDimension(
                R.styleable.RoundRelativeLayout_radius, 0);
    }

    private boolean isPathValid;
    private final Path path = new Path();

    private Path getRoundRectPath() {
        if (isPathValid) {
            return path;
        }

        path.reset();

        int width = getWidth();
        int height = getHeight();
        RectF bounds = new RectF(0, 0, width, height);

        path.addRoundRect(bounds, radius, radius, Direction.CCW);
        isPathValid = true;
        return path;
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.clipPath(getRoundRectPath());
        super.dispatchDraw(canvas);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.clipPath(getRoundRectPath());
        super.draw(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int oldWidth = getMeasuredWidth();
        int oldHeight = getMeasuredHeight();
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int newWidth = getMeasuredWidth();
        int newHeight = getMeasuredHeight();
        if (newWidth != oldWidth || newHeight != oldHeight) {
            isPathValid = false;
        }
    }

}
fishautumn
источник
1
Мне нравится этот подход. Я использовал его, чтобы создать свой собственный RoundImageView. Спасибо за это.
Паскаль
Это не работает при включенном ускорении, верно? Я не видел простого обходного пути ...
secureboot
Не могли бы вы показать, как это сделать, имея результат в качестве рисованного элемента, иметь возможность добавлять контур (обводку АКА) вокруг содержимого, а также иметь возможность делать только некоторые из углов, которые должны быть скруглены?
Android-разработчик
5

Далее создается объект макета с закругленными прямоугольниками, который рисует скругленный прямоугольник вокруг любых дочерних объектов, которые в нем размещены. Также демонстрируется, как программно создавать виды и макеты без использования XML-файлов макета.

package android.example;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MessageScreen extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  int mainBackgroundColor = Color.parseColor("#2E8B57");
  int labelTextColor = Color.parseColor("#FF4500");
  int messageBackgroundColor = Color.parseColor("#3300FF");
  int messageTextColor = Color.parseColor("#FFFF00");

  DisplayMetrics metrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(metrics);
  float density = metrics.density;
  int minMarginSize = Math.round(density * 8);
  int paddingSize = minMarginSize * 2;
  int maxMarginSize = minMarginSize * 4;

  TextView label = new TextView(this);
  /*
   * The LayoutParams are instructions to the Layout that will contain the
   * View for laying out the View, so you need to use the LayoutParams of
   * the Layout that will contain the View.
   */
  LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
  label.setLayoutParams(labelLayoutParams);
  label.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
  label.setPadding(paddingSize, paddingSize, paddingSize, paddingSize);
  label.setText(R.string.title);
  label.setTextColor(labelTextColor);

  TextView message = new TextView(this);
  RoundedRectangle.LayoutParams messageLayoutParams = new RoundedRectangle.LayoutParams(
 LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This tells the RoundedRectangle to put some extra space around the
   * View.
   */
  messageLayoutParams.setMargins(minMarginSize, paddingSize,
    minMarginSize, maxMarginSize);
  message.setLayoutParams(messageLayoutParams);
  message.setTextSize(TypedValue.COMPLEX_UNIT_SP, paddingSize);
  message.setText(R.string.message);
  message.setTextColor(messageTextColor);
  message.setBackgroundColor(messageBackgroundColor);

  RoundedRectangle messageContainer = new RoundedRectangle(this);
  LinearLayout.LayoutParams messageContainerLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  messageContainerLayoutParams.setMargins(paddingSize, 0, paddingSize, 0);
  messageContainer.setLayoutParams(messageContainerLayoutParams);
  messageContainer.setOrientation(LinearLayout.VERTICAL);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This tells the RoundedRectangle to color the the exta space that was
   * put around the View as well as the View. This is exterior color of
   * the RoundedRectangle.
   */
  messageContainer.setBackgroundColor(mainBackgroundColor);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This is the interior color of the RoundedRectangle. It must be
   * different than the exterior color of the RoundedRectangle or the
   * RoundedRectangle will not call its draw method.
   */
  messageContainer.setInteriorColor(messageBackgroundColor);
  // Add the message to the RoundedRectangle.
  messageContainer.addView(message);

  //
  LinearLayout main = new LinearLayout(this);
  LinearLayout.LayoutParams mainLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  main.setLayoutParams(mainLayoutParams);
  main.setOrientation(LinearLayout.VERTICAL);
  main.setBackgroundColor(mainBackgroundColor);
  main.addView(label);
  main.addView(messageContainer);

  setContentView(main);
 }
}

Класс для объекта макета RoundedRectangle определен здесь:

/**
 *  A LinearLayout that draws a rounded rectangle around the child View that was added to it.
 */
package android.example;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.LinearLayout;

/**
 * A LinearLayout that has rounded corners instead of square corners.
 * 
 * @author Danny Remington
 * 
 * @see LinearLayout
 * 
 */
public class RoundedRectangle extends LinearLayout {
 private int mInteriorColor;

 public RoundedRectangle(Context p_context) {
  super(p_context);
 }

 public RoundedRectangle(Context p_context, AttributeSet attributeSet) {
  super(p_context, attributeSet);
 }

 // Listener for the onDraw event that occurs when the Layout is drawn.
 protected void onDraw(Canvas canvas) {
  Rect rect = new Rect(0, 0, getWidth(), getHeight());
  RectF rectF = new RectF(rect);
  DisplayMetrics metrics = new DisplayMetrics();
  Activity activity = (Activity) getContext();
  activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
  float density = metrics.density;
  int arcSize = Math.round(density * 10);

  Paint paint = new Paint();
  paint.setColor(mInteriorColor);

  canvas.drawRoundRect(rectF, arcSize, arcSize, paint);
 }

 /**
  * Set the background color to use inside the RoundedRectangle.
  * 
  * @param Primitive int - The color inside the rounded rectangle.
  */
 public void setInteriorColor(int interiorColor) {
  mInteriorColor = interiorColor;
 }

 /**
  * Get the background color used inside the RoundedRectangle.
  * 
  * @return Primitive int - The color inside the rounded rectangle.
  */
 public int getInteriorColor() {
  return mInteriorColor;
 }

}
Дэнни Ремингтон - OMS
источник
5

Котлин

import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
rounded.cornerRadius = 20f
profileImageView.setImageDrawable(rounded)

Чтобы сделать ImageViewциркуляр мы можем изменить cornerRadiusс помощью:

rounded.isCircular = true
Вахид
источник
4

Большое спасибо за первый ответ. Здесь модифицированная версия для преобразования прямоугольного изображения в квадратное (и округленное), а цвет заливки передается в качестве параметра.

public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) {

    Bitmap inpBitmap = bitmap;
    int width = 0;
    int height = 0;
    width = inpBitmap.getWidth();
    height = inpBitmap.getHeight();

    if (width <= height) {
        height = width;
    } else {
        width = height;
    }

    Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, width, height);
    final RectF rectF = new RectF(rect);
    final float roundPx = pixels;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(inpBitmap, rect, rect, paint);

    return output;
}
мКМ
источник
4

Если вы используете Glide Library, это будет полезно:

Glide.with(getApplicationContext())
     .load(image_url)
     .asBitmap()
     .centerCrop()
     .into(new BitmapImageViewTarget(imageView) {
        @Override
        protected void setResource(Bitmap resource) {
          RoundedBitmapDrawable circularBitmapDrawable =
                       RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource);
          circularBitmapDrawable.setCornerRadius(dpToPx(10));
          circularBitmapDrawable.setAntiAlias(true);
          imageView.setImageDrawable(circularBitmapDrawable);
        }
     });


public int dpToPx(int dp) {
  DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
  return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
Anirudh
источник
Если используется Glide версии 4 и выше, используйте --- RequestOptions requestOptions = new RequestOptions (); requestOptions = requestOptions.transforms (new CenterCrop (), new RoundedCorners (16)); Glide.with (itemView.getContext ()) .load (item.getImage ()) .apply (requestOptions) .into (mProgramThumbnail);
Б. Шрути
3

если ваше изображение в Интернете, лучше всего использовать glide и RoundedBitmapDrawableFactory(из API 21 - но доступно в библиотеке поддержки), например:

 Glide.with(ctx).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) {
    @Override
    protected void setResource(Bitmap res) {
        RoundedBitmapDrawable bitmapDrawable =
             RoundedBitmapDrawableFactory.create(ctx.getResources(), res);
        bitmapDrawable.setCircular(true);//comment this line and uncomment the next line if you dont want it fully cricular
        //circularBitmapDrawable.setCornerRadius(cornerRadius);
        imageView.setImageDrawable(bitmapDrawable);
    }
});
Амир Зиарати
источник
Это элегантный API, однако, .centerInside, кажется, отсутствует, поэтому, возможно, лучше использовать xml для определения таких параметров
carl
Это также полезно, когда изображение находится в ресурсах, и вам нужно использоватьcenterCrop
Артём
3

Вы можете использовать только ImageViewв вашем макете и с glideпомощью этого метода вы можете применять закругленные углы.

сначала в твоей гадости пиши,

compile 'com.github.bumptech.glide:glide:3.7.0'

для изображения с закругленными углами,

public void loadImageWithCorners(String url, ImageView view) {
    Glide.with(context)
            .load(url)
            .asBitmap()
            .centerCrop()
            .placeholder(R.color.gray)
            .error(R.color.gray)
            .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .into(new BitmapImageViewTarget(view) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable =
                            RoundedBitmapDrawableFactory.create(context.getResources(), resource);
                    circularBitmapDrawable.setCornerRadius(32.0f); // radius for corners
                    view.setImageDrawable(circularBitmapDrawable);
                }
            });
}

вызов метода:

loadImageWithCorners("your url","your imageview");
Глубокий Патель
источник
Это добавит библиотеку для загрузки изображений через HTTP-запрос, который не имеет отношения к вопросу.
creativecreatorormaybenot
Какая библиотека будет загружена? Для загрузки изображения вы можете использовать glide и его фрагмент, основанный исключительно на методах и классах самого glide. Никакая другая библиотека не должна быть добавлена
Deep Patel
Glide - это библиотека, в основном для загрузки изображений по HTTP, но OP хотел знать, как закруглить углы ImageView.
creativecreatorormaybenot
2

Ответьте на вопрос, который перенаправлен сюда: «Как создать круговой ImageView в Android?»

public static Bitmap getRoundBitmap(Bitmap bitmap) {

    int min = Math.min(bitmap.getWidth(), bitmap.getHeight());

    Bitmap bitmapRounded = Bitmap.createBitmap(min, min, bitmap.getConfig());

    Canvas canvas = new Canvas(bitmapRounded);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min/2, min/2, paint);

    return bitmapRounded;
}
Андрей
источник
2

С помощью библиотеки glide и класса RoundedBitmapDrawableFactory этого легко достичь. Возможно, вам потребуется создать круглое изображение заполнителя.

    Glide.with(context)
        .load(imgUrl)
        .asBitmap()
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.placeholder)
        .into(new BitmapImageViewTarget(imgProfilePicture) {
            @Override
            protected void setResource(Bitmap resource) {
                RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
                        Bitmap.createScaledBitmap(resource, 50, 50, false));
                drawable.setCornerRadius(10); //drawable.setCircular(true);
                imgProfilePicture.setImageDrawable(drawable);
            }
        });
Chitrang
источник
2

Для тех, кто использует Glide и Kotlin, вы можете добиться этого, расширив RequestBuilder

fun <T> GlideRequest<T>.roundCorners(cornerRadius: Int) =
    apply(RequestOptions().transform(RoundedCorners(cornerRadius)))

и использовать как;

 GlideApp.with(context)
            .load(url)
            .roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
            .into(imgView)
dgngulcan
источник
.NetCorners не приходят нам нужно что-то еще настроить?
Доктор Андро
Вы добавили функцию расширения, roundCornersкак указано выше? @ Dr.aNdRO
dgngulcan
Пожалуйста, предоставьте правильный пример! Этот ответ сбивает с толку!
Джуния Монтана