Jak zaokrąglić obraz za pomocą biblioteki Glide?


197

Czy ktoś wie, jak wyświetlić obraz z zaokrąglonymi narożnikami za pomocą Glide? Ładuję obraz za pomocą Glide, ale nie wiem, jak przekazać zaokrąglone parametry do tej biblioteki.

Potrzebuję wyświetlanego obrazu, jak w poniższym przykładzie:

wprowadź opis zdjęcia tutaj


2
korzystam z github.com/hdodenhof/CircleImageView do podglądu obrazu
MilapTank

1
Wiem, jak korzystać z Glide lib z CircleImageView, ale szukam możliwego sposobu, aby to zrobić tylko z Glide lib. Masz jakąś metodę w Glide lib, aby to zrobić lub nie jest obsługiwana?
mr.boyfox

Odpowiedzi:


487

Glide V4:

    Glide.with(context)
        .load(url)
        .circleCrop()
        .into(imageView);

Glide V3:

Możesz używać RoundedBitmapDrawabledo okrągłych obrazów z Glide. Nie jest wymagany niestandardowy ImageView.

 Glide.with(context).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable =
                    RoundedBitmapDrawableFactory.create(context.getResources(), resource);
            circularBitmapDrawable.setCircular(true);
            imageView.setImageDrawable(circularBitmapDrawable);
        }
    });

6
nie tworzy to jednak granicy.
ZakTaccardi

1
@ jimmy0251 Nie, nie możesz. Drawable poślizgu nie są BitmapDrawables. Są to rysunki przejściowe i ruchome, które przechodzą od symbolu zastępczego do rzeczywistego obrazu. RoundedBitmapDrawable nie może tego obsłużyć.
Greg Ennis

7
ustaw tło z wysuwanym owalnym kształtem. i dodaj dopełnienie do podglądu obrazu w celu utworzenia obramowania.
Lalit Jadav

2
Jeśli masz jakiś problem, SPRAWDŹ NASTĘPNE ROZWIĄZANIE Romana Samoylenko, które działa.
Pabel

1
Zamiast .centerCrop()ciebie prawdopodobnie oznacza.circleCrop()
Thanasis Kapelonis

66

Sprawdź ten post, glide vs picasso ...
Edytuj : połączony post nie wywołuje istotnej różnicy w bibliotekach. Glide dokonuje recyklingu automatycznie. Zobacz komentarz TWiStErRob, aby uzyskać więcej.

Glide.with(this).load(URL).transform(new CircleTransform(context)).into(imageView);

public static class CircleTransform extends BitmapTransformation {
    public CircleTransform(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;

        // TODO this could be acquired from the pool too
        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();
    }
} 

brzmi interesująco. Czy działa dobrze z Zarysem API 21?
Teovald

hmm, mógłbym to wtedy wykorzystać. Spróbuję po prostu użyć niestandardowego widoku, nie chcę tworzyć drugiej mapy bitowej :). Ponadto należy zawsze korzystać z puli bitmap, aby uzyskać stamtąd bitmapę :)
Teovald,

Uważaj na użycie public String getId()sposobu pokazanego w kodzie, ponieważ zwraca ten sam identyfikator dla wszystkich obrazów, dlatego może się zdarzyć, że poślizg ustawi stare zaokrąglone obrazy, a bez przekształceń ustawi prawidłowy obraz! Nie wiem, jak działa poślizg, ale wydaje się, że buforuje transformacje obrazów (zakładam, że w celu uniknięcia twardych łydek). I identyfikator jest używany jako identyfikator przekształconego obrazu. Dodałem adres URL obrazu do konstruktora i sprawiłem, że wspomniana metoda zwraca wynikowy identyfikator, taki jak:this.id = String.format("%s:%s",this.getClass().getSimpleName(),id);
Stan

2
Jedynym wymaganiem dotyczącym identyfikatorów transformacji jest to, że są one unikalne wśród wszystkich transformacji, więc użycie tutaj jest prawidłowe. Klucze pamięci podręcznej będą zawierać zarówno identyfikator źródłowy, jak i identyfikator transformacji, więc identyfikator transformacji jest raczej mixinem niż zamiennikiem. Zobacz github.com/bumptech/glide/wiki/…
Sam Judd

4
Czy istnieje sposób zastosowania transformacji do symbolu zastępczego?
Sinigami,

45

Najłatwiejszy sposób (wymaga Glide 4.xx)

Glide.with(context).load(uri).apply(RequestOptions().circleCrop()).into(imageView)

to nawet nie kompiluje ... RequestOptions ()?
Rafael Lima

3
@RafaelLima Jest napisany w Kotlinie.
Roman Samoylenko

1
Zauważ, że to .apply()nastąpi .load().
Johnny Five,

jest RequestOptions.circleCropTransform (), a nie RequestOptions ().
Uśmiecha się

musisz napisać Glide.with (kontekst) .load (uri) .apply (circleCrop ()). w (imageView) spójrz na funkcję Apply.
Jaspal

25

Wypróbuj w ten sposób

kod

Glide.with(this)
    .load(R.drawable.thumbnail)
    .bitmapTransform(new CropCircleTransformation(this))
    .into(mProfile);

XML

<ImageView
  android:id="@+id/img_profile"
  android:layout_width="76dp"
  android:layout_height="76dp"
  android:background="@drawable/all_circle_white_bg"
  android:padding="1dp"/>

all_circle_white_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <shape android:shape="oval">
      <solid android:color="@android:color/white"/>
  </shape>
  </item>
</selector>

9

jego bardzo proste Widziałem bibliotekę Glide, bardzo dobrą bibliotekę i esej na temat biblioteki Volley Google

użyj tej biblioteki do zaokrąglonego widoku obrazu

https://github.com/hdodenhof/CircleImageView

teraz

// Dla prostego widoku:

 @Override
 public void onCreate(Bundle savedInstanceState) {
  ...

  CircleImageView civProfilePic = (CircleImageView)findViewById(R.id.ivProfile);
  Glide.load("http://goo.gl/h8qOq7").into(civProfilePic);
}

// Aby uzyskać listę:

@Override
public View getView(int position, View recycled, ViewGroup container) {
final ImageView myImageView;
 if (recycled == null) {
    myImageView = (CircleImageView) inflater.inflate(R.layout.my_image_view,
            container, false);
} else {
    myImageView = (CircleImageView) recycled;
}

String url = myUrls.get(position);

Glide.load(url)
    .centerCrop()
    .placeholder(R.drawable.loading_spinner)
    .animate(R.anim.fade_in)
    .into(myImageView);

  return myImageView;
}

i w XML

<de.hdodenhof.circleimageview.CircleImageView
   android:id="@+id/ivProfile
   android:layout_width="160dp"
   android:layout_height="160dp"
   android:layout_centerInParent="true"
   android:src="@drawable/hugh"
   app:border_width="2dp"
   app:border_color="@color/dark" />

2
Jak wspomniano w komentarzu do poprzedniej odpowiedzi, ten sposób również nie działa dobrze. Przynajmniej dla 'de.hdodenhof: circleimageview: 1.2.2' + 'com.github.bumptech.glide: glide: 3.5.2'. Sprawdzone i dwukrotnie sprawdzone. Również ten sam problem z glide 3.4. + I circleimageview 1.2.1
Stan

+1 dla .centerCrop (). Pracował dla mnie z DiamondImageView plus .asBitmap ().
felippe,

1
Wymaga wywołania .dontAnimate () na glide, co jest niedopuszczalne
Greg Ennis

+1 Należy jednak pamiętać, że ładowanie obrazów internetowych za pomocą Glide
jeż

9

Inne rozwiązania nie działały dla mnie. Odkryłem, że wszystkie mają znaczące wady:

  • Rozwiązania wykorzystujące transformacje poślizgu nie działają z symbolami zastępczymi
  • Rozwiązania wykorzystujące zaokrąglone widoki obrazu nie działają z animacjami (tj. Płynne przejście)
  • Rozwiązania wykorzystujące ogólną metodę rodzica, która przycina swoje dzieci (tj. Tutaj przyjęta odpowiedź ), nie działają dobrze z poślizgiem

To naprawdę interesujące, że po tym, jak się z tym pogrzebałem, znalazłem stronę biblioteki Fresco o zaokrąglonych rogach i okręgach, w których wymieniają w zasadzie te same ograniczenia i kończą stwierdzeniem:

na Androida nie ma naprawdę dobrego rozwiązania do zaokrąglania rogów i trzeba wybierać między wymienionymi wyżej kompromisami

Niewiarygodne, że w tej chwili wciąż nie mamy realnego rozwiązania. Mam alternatywne rozwiązanie oparte na linku, który podałem powyżej. Wadą tego podejścia jest to, że zakłada, że ​​tło ma jednolity kolor (narożniki nie są tak naprawdę przezroczyste). Użyłbyś tego w ten sposób:

<RoundedCornerLayout ...>
    <ImageView ...>
</RoundedCornerLayout>

Istota jest tutaj, a pełny kod tutaj:

public class RoundedCornerLayout extends RelativeLayout {
    private Bitmap maskBitmap;
    private Paint paint;
    private float cornerRadius;

    public RoundedCornerLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

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

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

    private void init(Context context, AttributeSet attrs, int defStyle) {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        setWillNotDraw(false);
    }

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

        if (maskBitmap == null) {
            // This corner radius assumes the image width == height and you want it to be circular
            // Otherwise, customize the radius as needed
            cornerRadius = canvas.getWidth() / 2;
            maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
        }

        canvas.drawBitmap(maskBitmap, 0f, 0f, paint);
    }

    private Bitmap createMask(int width, int height) {
        Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mask);

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE); // TODO set your background color as needed

        canvas.drawRect(0, 0, width, height, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);

        return mask;
    }
}

6

Teraz w Glide V4 możesz bezpośrednio używać CircleCrop ()

Glide.with(fragment)
  .load(url)
  .circleCrop()
  .into(imageView);

Wbudowane typy

  • CenterCrop
  • FitCenter
  • CircleCrop

5

Użyj tej transformacji, będzie działać dobrze.

public class CircleTransform extends BitmapTransformation {
public CircleTransform(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 borderColor = ColorUtils.setAlphaComponent(Color.WHITE, 0xFF);
    int borderRadius = 3;

    int size = Math.min(source.getWidth(), source.getHeight());
    int x = (source.getWidth() - size) / 2;
    int y = (source.getHeight() - size) / 2;

    // TODO this could be acquired from the pool too
    Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
    if (squared != source) {
        source.recycle();
    }

    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);

    // Prepare the background
    Paint paintBg = new Paint();
    paintBg.setColor(borderColor);
    paintBg.setAntiAlias(true);

    // Draw the background circle
    canvas.drawCircle(r, r, r, paintBg);

    // Draw the image smaller than the background so a little border will be seen
    canvas.drawCircle(r, r, r - borderRadius, paint);

    squared.recycle();

    return result;
}

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

5

Dla Glide 4.xx

posługiwać się

Glide
  .with(context)
  .load(uri)
  .apply(
      RequestOptions()
        .circleCrop())
  .into(imageView)

z dokumentu stwierdzono, że

Okrągłe zdjęcia: CircleImageView / CircularImageView / RoundedImageView mają problemy z TransitionDrawable (.crossFade () z .thumbnail () lub .placeholder ()) i animowanymi GIF- ami , użyj BitmapTransformation (.circleCrop () będzie dostępny w v4) lub .dontAnimate (), aby rozwiązać problem


4

Zgodnie z odpowiedzią najłatwiejszym sposobem w obu językach jest:

Kotlin:

Glide.with(context).load(uri).apply(RequestOptions().circleCrop()).into(imageView)

Jawa:

Glide.with(context).load(uri).apply(new RequestOptions().circleCrop()).into(imageView)

Działa na Glide 4.XX


4

Odpowiedź Romana Samojlenko była prawidłowa, z wyjątkiem zmiany funkcji. Poprawna odpowiedź to

Glide.with(context)
                .load(yourImage)
                .apply(RequestOptions.circleCropTransform())
                .into(imageView);

3

Znalazłem jedno łatwe i proste rozwiązanie do dodawania obramowania na widok obrazu, w którym kolor chcesz ustawić lub dodać gradient na obrazie.

KROKI:

  1. Wybierz jeden układ ramki i dodaj dwa obrazy. Możesz ustawić rozmiar zgodnie z wymaganiami. Do tego imgPlaceHolderpotrzebujesz jednego białego obrazu lub koloru, który chcesz ustawić.

        <ImageView
            android:id="@+id/imgPlaceHolder"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:src="@drawable/white_bg"/>

        <ImageView
            android:id="@+id/imgPic"
            android:layout_width="190dp"
            android:layout_height="190dp"
            android:layout_gravity="center"
            android:src="@drawable/image01"/>
    </FrameLayout>
  1. Po umieszczeniu tego kodu w pliku xml, umieść poniżej wiersza w pliku Java.

    Glide.with(this).load(R.drawable.image01).asBitmap().centerCrop().into(new BitmapImageViewTarget(imgPic) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable =
                    RoundedBitmapDrawableFactory.create(getResources(), resource);
            circularBitmapDrawable.setCircular(true);
            imageView.setImageDrawable(circularBitmapDrawable);
        }
    });
    
    Glide.with(this).load(R.drawable.white_bg).asBitmap().centerCrop().into(new BitmapImageViewTarget(imgPlaceHolder) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable =
                    RoundedBitmapDrawableFactory.create(getResources(), resource);
            circularBitmapDrawable.setCircular(true);
            imgTemp2.setImageDrawable(circularBitmapDrawable);
        }
    });

To sprawi, że obramowanie podglądu obrazu będzie po prostu bez dodatkowego dopełnienia i marginesu.

UWAGA : Biały obraz jest obowiązkowy dla obramowania, w przeciwnym razie nie będzie działał.

Miłego kodowania :)


3

Z biblioteką poślizgową możesz użyć tego kodu:

Glide.with(context)
    .load(imageUrl)
    .asBitmap()
    .placeholder(R.drawable.user_pic)
    .centerCrop()
    .into(new BitmapImageViewTarget(img_profPic) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource);

            circularBitmapDrawable.setCircular(true);
            img_profPic.setImageDrawable(circularBitmapDrawable);
        }
    });

możesz również wykonać zaokrąglony obraz za pomocą biblioteki glid.
priti

2

Szukałem go wcześniej i zrobiłem to w najprostszy sposób, mam nadzieję, że ci się spodoba.

 //crete this method into your Utils class and call this method wherever you want to use.
    //you can set these placeHolder() and error() image static as well. I made it as comment inside this method, then no need to use [placeHolderUrl and errorImageUrl] parameters. remove it from this method.
    public static void loadImage(final Activity context, ImageView imageView, String url, int placeHolderUrl, int errorImageUrl) {
        if (context == null || context.isDestroyed()) return;

        //placeHolderUrl=R.drawable.ic_user;
        //errorImageUrl=R.drawable.ic_error;
            Glide.with(context) //passing context
                    .load(getFullUrl(url)) //passing your url to load image.
                    .placeholder(placeHolderUrl) //this would be your default image (like default profile or logo etc). it would be loaded at initial time and it will replace with your loaded image once glide successfully load image using url.
                    .error(errorImageUrl)//in case of any glide exception or not able to download then this image will be appear . if you won't mention this error() then nothing to worry placeHolder image would be remain as it is.
                    .diskCacheStrategy(DiskCacheStrategy.ALL) //using to load into cache then second time it will load fast.
                    .transform(new CircleTransform(context))//this CircleTransform class help to crop an image as circle.
                    .animate(R.anim.fade_in) // when image (url) will be loaded by glide then this face in animation help to replace url image in the place of placeHolder (default) image.
                    .fitCenter()//this method help to fit image into center of your ImageView
                    .into(imageView); //pass imageView reference to appear the image.
    } 

CircleTransform.java

  public class CircleTransform extends BitmapTransformation {
    public CircleTransform(Context context) {
        super(context);

        if(context==null)
            return;
    }

    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
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

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

fade_in.xml do przejścia w animacji.

    <set xmlns:android="http://schemas.android.com/apk/res/android">
<!--THIS ANIMATION IS USING FOR FADE IN -->

<alpha
    android:duration="800"
    android:fromAlpha="0.0"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:toAlpha="1.0" />

wreszcie wywołać tę metodę.

Utils.loadImage(YourClassName.this,mImageView,url,R.drawable.ic_user,R.drawable.ic_error);

2

Możesz po prostu wywołać konstruktor RoundedCornersTransformation, który ma wejście enum cornerType. Lubię to:

Glide.with(context)
            .load(bizList.get(position).getCover())
            .bitmapTransform(new RoundedCornersTransformation(context,20,0, RoundedCornersTransformation.CornerType.TOP))
            .into(holder.bizCellCoverImg);

ale najpierw musisz dodać Glide Transformations do swojego projektu.


2

Oto bardziej modułowy i czystszy sposób na wykadrowanie mapy bitowej w Glide:

  1. Utwórz niestandardową transformację, rozszerzając, BitmapTransformationa następnie zastąp transformmetodę:

Dla Glide 4.xx

public class CircularTransformation extends BitmapTransformation {

@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
    RoundedBitmapDrawable circularBitmapDrawable =
            RoundedBitmapDrawableFactory.create(null, toTransform);
    circularBitmapDrawable.setCircular(true);
    Bitmap bitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    circularBitmapDrawable.setBounds(0, 0, outWidth, outHeight);
    circularBitmapDrawable.draw(canvas);
    return bitmap;
    }

@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {}

}

Dla Glide 3.xx

public class CircularTransformation extends BitmapTransformation {

@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
    RoundedBitmapDrawable circularBitmapDrawable =
            RoundedBitmapDrawableFactory.create(null, toTransform);
    circularBitmapDrawable.setCircular(true);
    Bitmap bitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    circularBitmapDrawable.setBounds(0, 0, outWidth, outHeight);
    circularBitmapDrawable.draw(canvas);
    return bitmap;
    }

@Override
public String getId() {
    // Return some id that uniquely identifies your transformation.
    return "CircularTransformation";
    }

}
  1. Następnie ustaw go w kreatorze Glide tam, gdzie jest to potrzebne:
Glide.with(yourActivity)
   .load(yourUrl)
   .asBitmap()
   .transform(new CircularTransformation())
   .into(yourView);

Mam nadzieję że to pomoże :)


2
private void setContactImage(@NonNull ViewHolder holder, ClsContactDetails clsContactDetails) {
    Glide.with(context).load(clsContactDetails.getPic())
        .apply(new RequestOptions().centerCrop().circleCrop().placeholder(R.mipmap.ic_launcher)).into(holder.ivPersonImage);
}

2
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'


RequestOptions options=new RequestOptions();
        options.centerCrop().placeholder(getResources().getDrawable(R.drawable.user_placeholder));
        Glide.with(this)
                .load(preferenceSingleTon.getImage())
                .apply(options)
                .into(ProfileImage);

2

Przycinanie kół + symbol zastępczy + przenikanie

 Glide.with(context!!)
                    .load(randomImage)
                    .apply(RequestOptions.bitmapTransform(CircleCrop()).error(R.drawable.nyancat_animated))
                    .transition(DrawableTransitionOptions()
                            .crossFade())
                    .into(picture)

wprowadź opis zdjęcia tutaj


1

Wersja szybująca 4.6.1

Glide.with(context)
.load(url)
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
.into(imageView);

1

W takim przypadku muszę dodać cienie, a elewacja imageView nie działa

wdrożenie "com.github.bumptech.glide: glide: 4.10.0"

XML

<FrameLayout
    android:id="@+id/fl_image"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_margin="10dp"
    android:background="@drawable/card_circle_background"
    android:elevation="8dp">

    <ImageView
        android:id="@+id/iv_item_employee"
        android:layout_width="60dp"
        android:layout_height="60dp"
        tools:background="@color/colorPrimary" />
</FrameLayout>

Kształt do wyciągnięcia

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">
     <solid android:color="@color/white"/>
</shape>

Konfiguracja poślizgu

Glide.with(this)
    .asBitmap()
    .load(item.image)
    .apply(RequestOptions.circleCropTransform())
    .into(iv_item_employee)

0

Musisz użyć CircularImageView, aby wyświetlić ten typ obrazu ...

Używasz biblioteki Glide, która służyła do ładowania obrazów ..

Utwórz jeden plik klasy w swoim projekcie i załaduj go do programu Imageview ... a otrzymasz pożądany wynik ...

Wypróbuj następujący kod ...

XML

 <com.yourpackage.CircularImageView
    android:id="@+id/imageview"
    android:layout_width="96dp"
    android:layout_height="96dp"
    app:border="true"
    app:border_width="3dp"
    app:border_color="@color/white"
    android:src="@drawable/image" />

CircularImageView.java

public class CircularImageView extends ImageView {
    private int borderWidth;
    private int canvasSize;
    private Bitmap image;
    private Paint paint;
    private Paint paintBorder;

    public CircularImageView(final Context context) {
        this(context, null);
    }

    public CircularImageView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.circularImageViewStyle);
    }

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

        // init paint
        paint = new Paint();
        paint.setAntiAlias(true);

        paintBorder = new Paint();
        paintBorder.setAntiAlias(true);

        // load the styled attributes and set their properties
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);

        if(attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
            int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
            setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
            setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
        }

        if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
            addShadow();
    }

    public void setBorderWidth(int borderWidth) {
        this.borderWidth = borderWidth;
        this.requestLayout();
        this.invalidate();
    }

    public void setBorderColor(int borderColor) {
        if (paintBorder != null)
            paintBorder.setColor(borderColor);
        this.invalidate();
    }

    public void addShadow() {
        setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
        paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
    }

    @Override
    public void onDraw(Canvas canvas) {
        // load the bitmap
        image = drawableToBitmap(getDrawable());

        // init shader
        if (image != null) {

            canvasSize = canvas.getWidth();
            if(canvas.getHeight()<canvasSize)
                canvasSize = canvas.getHeight();

            BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint.setShader(shader);

            // circleCenter is the x or y of the view's center
            // radius is the radius in pixels of the cirle to be drawn
            // paint contains the shader that will texture the shape
            int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // The parent has determined an exact size for the child.
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // The parent has not imposed any constraint on the child.
            result = canvasSize;
        }

        return result;
    }

    private int measureHeight(int measureSpecHeight) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpecHeight);
        int specSize = MeasureSpec.getSize(measureSpecHeight);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // Measure the text (beware: ascent is a negative number)
            result = canvasSize;
        }

        return (result + 2);
    }

    public Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable == null) {
            return null;
        } else if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }
}

Uwaga :

Możesz użyć

CircularImageView imgIcon = (CircularImageView)findViewById(R.id.imageview);

lub

ImageView imgIcon = (ImageView)findViewById(R.id.imageview);

nie wpłynie to na inne biblioteki ... nie musisz zmieniać kodu do pobierania obrazu lub czegokolwiek innego ... po prostu można go zdefiniować za pomocą XML ..


3
Próbowałem Glide + CircularImageView (i RoundedImageView) i nie działa dobrze, jeśli zaczniesz używać symboli zastępczych (podczas pobierania obrazu) i animacji wyglądu. Picasso nie ma tego problemu. Więcej informacji na ten temat można znaleźć tutaj: github.com/vinc3m1/RoundedImageView/issues/76
zmicer

Wystarczy użyć .asBitmap w wywołaniu Glide, a będzie działać dobrze.
granko87

Wymaga wywołania .dontAnimate () na glide, co jest niedopuszczalne
Greg Ennis
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.