Köşeleri yuvarlatılmış bir ImageView nasıl yapılır?


573

Android'de, ImageView varsayılan olarak bir dikdörtgendir. ImageView'de nasıl yuvarlatılmış bir dikdörtgen yapabilirim (Bitmap'imin 4 köşesinin tamamını yuvarlayabilirsiniz)?



Eski, daha karmaşık cevapların altında gizli, şimdi kabul edilen cevap olması gerektiğini düşünüyorum: RoundedBitmapDrawable , v4 Destek Kütüphanesi revizyonu 21'e eklendi.
Jonik

CardView'ı içeride bir ImageView ile kullanmak için en kolay yolu yapabilirsiniz - buradaki örneğe bakın stackoverflow.com/a/41479670/4516797
Taras Vovkovych

Bu kütüphane çok faydalı.
grrigore

Elimizdeki şimdi bu kontrol ShapeableImageViewdairesel veya yuvarlak imageview yapmak stackoverflow.com/a/61086632/7666442
Nilesh Rathod

Yanıtlar:


544

Bu, yanıt olarak oldukça geç, ancak bunu arayan herkes için, görüntülerinizin köşelerini manuel olarak döndürmek için aşağıdaki kodu yapabilirsiniz.

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

Bu benim kodum değil, ama kullandım ve harika çalışıyor. Bir ImageHelper sınıfı içinde yardımcı olarak kullandım ve belirli bir görüntü için ihtiyacım olan geçiş yumuşatma miktarını geçmek için biraz uzattım.

Son kod şöyle görünür:

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

Umarım bu birine yardımcı olur!


4
Tüm cihazlar için çalışmaz.
Bahar Kırıcı

7
200 * 200 resim için bunu yapmak yaklaşık 0,03 saniye sürer, bu yüzden bunun en iyi çözüm olmadığını düşünüyorum.
Jacky

2
Sadece sol üst ve sağ üst köşeleri yuvarlar. Neden ?
Prateek

1
@ vinc3m1 çözüm burada github.com/makeramen/RoundedImageView gerçekten iyi çalışıyor! ayrıca cevabına bakınız ( stackoverflow.com/a/15032283/2048266 )
nommer

16
Imageview'ın scaletype'ı ayarlamaya çalışırken iyi çalışmıyor, sadece fitXY çalışıyor, centerCrop ve diğer tahmin edilemeyen sonuçlar gösteriyor, burada herkes aynı sorunları var mı?
Shivansh

211

Yukarıdaki cevap işe yararken, Romain Guy (temel bir Android geliştiricisi) blogunda, bitmap'in bir kopyasını oluşturmayan bir gölgelendirici kullanarak daha az bellek kullanan daha iyi bir yöntem gösteriyor . İşlevselliğin genel özeti burada:

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

Bunun diğer yöntemlere göre avantajları:

  • büyük resimlerle çok fazla bellek kullanan bitmap'in ayrı bir kopyasını oluşturmaz [diğer cevapların çoğuna karşı]
  • kenar yumuşatmayı destekler [vs clipPath yöntemi]
  • alfa destekliyor [vs xfermode + porterduff yöntemi]
  • donanım hızlandırmayı destekler [vs clipPath yöntemi]
  • tuvale sadece bir kez çizer [xfermode ve clippath yöntemlerine karşı]

Bu mantığı bir ImageView içine sarar ve uygun destek ve isteğe bağlı yuvarlak kenarlık ekler bu kodu temel alan bir RoundedImageView oluşturdum ScaleType.


Gözlerinde farklı / example / res / layout / rounded_item.xml tüm kaynaklar önceden kodlanmıştır zaman neden bir görüntü src belirtebilirim? Güzel demo, sadece yol overkill.
Bir Yerde

örneğin, orijinal Romain Guy örneği gibi, hafızanızda ciddi bir sorun var. Hala neyin neden olduğunu bilmiyorum, ama sadece onun kodu gibi, bu bulmak gerçekten zor bir şey. OOM nedeniyle uygulamadan bir kilitlenme göremiyorsanız, gerçekleşene kadar uygulamayı birden fazla kez döndürebilirsiniz (cihazınıza, ROM'a vb. Bağlıdır). Burada geçmişte rapor ettim: stackoverflow.com/questions/14109187/…
android geliştirici

1
Başka kimse bellek yetersizliğini bildirmiyor, bu yüzden yanlış kodun dışında yaptığınız bir şey olmalı. Örnek doğru adaptörü bit eşlem sınırlı sayıda sahip olmadan onları görüntü elde edilmiştir her yeniden. Burada gösterilen örnek, Çizelgedeki draw () yönteminin snippet'idir; bu, tuttuğu orijinal bitmap referansını kullanır ve düzgün çalışır. O edilir değil orijinal bitmap değişebilir ama sadece yuvarlatılmış köşeler ile işlemek için geliyordu. Merkez kırpma örnekte de iyi çalışıyor.
vinc3m1

1
Çalışmadığı yerlerde ekran görüntüleri veya cihazlar sağlayabilir, hatta bir düzeltme ve çekme isteği sunma kadar ileri gidebilirseniz, bu en üretken olacaktır. Cihazlarımda birden fazla kez döndürmeyi test ettim ve bellek aynı kalıyor.
vinc3m1

11
Görüntü boyutu 2048 pikselin üzerindeyse çalışmaz. Gölgelendirici bundan daha büyük bir dokuyu desteklemez.
Gábor

209

Bir başka kolay yol da köşe yarıçapı ve içerisindeki bir ImageView ile CardView kullanmaktır:

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

resim açıklamasını buraya girin


5
İyi bir çözüm gibi görünüyor. Ancak lolipop öncesi görüntüleri kırpmaz.
Nikolai

1
Ya sadece sol üst ve sağ üst köşelerde yarıçap istiyoruz, tüm köşelerde değil?
Pratik Singhal

3
Herhangi bir görünümde eğri kenarlığı uygulamak için çok basit ve akıllı bir yol.
AMI CHARADAVA

1
İyi bir çözüm ancak yükseklik sadece 21. Ve üstü api seviyelerinde desteklenir
Saad Bilal

1
Kart yükselmesini devre dışı bırakmak için app kullanın: cardElevation = "0dp" (android değil: yükseklik)
Johnny Five

149

Yuvarlak şekillere kırpma ViewAPI 21'de sınıfa eklendi .

Sadece bunu yap:

  • Böyle bir şey çizilebilir yuvarlak bir şekil oluşturun:

res / çekilebilir / round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>
  • Çekmeceyi ImageView'in arka planı olarak ayarlayın: android:background="@drawable/round_outline"
  • Bu belgelere göre , yapmanız gereken tek şeyandroid:clipToOutline="true"

Ne yazık ki, bir hata var ve bu XML özelliği tanınmıyor. Neyse ki, yine de Java'da kırpma ayarlayabiliriz:

  • Faaliyetinizde veya parçanızda: ImageView.setClipToOutline(true)

İşte böyle görünecek:

resim açıklamasını buraya girin

Not:

Bu yöntem herhangi bir çekilebilir şekil için çalışır (sadece yuvarlak değil). ImageView'i Çekilebilir xml'nizde tanımladığınız şekil anahattına kırpacaktır.

ImageViews hakkında özel not

setClipToOutline()yalnızca Görünüm'ün arka planı çekilebilir bir şekle ayarlandığında çalışır. Bu arka plan şekli varsa, Görünüm şeklin dış çizgisine kırpma ve gölgeleme amacıyla kenarlık olarak davranır.

Bu setClipToOutline(), bir ImageView üzerindeki köşeleri yuvarlamak için kullanmak istiyorsanız , görüntünüzün android:srcyerine android:background( Görüntünüzü src yerine ayarlamak için arka plan kullanmanız GEREKİRSE, bu geçici çözümü kullanabilirsiniz:

  • Bir düzen oluşturun ve arka planını çizilebilir şekline ayarlayın
  • Bu düzeni ImageView'inize sarın (dolgu olmadan)
  • ImageView (mizanpajdaki herhangi bir şey dahil) şimdi yuvarlatılmış mizanpaj şeklinde görüntülenecektir.

10
Hata: (x) 'android' paketindeki 'clipToOutline' özelliği için kaynak tanımlayıcı bulunamadı
Anu Martin

7
Bunun yerine android:clipToOutline, kişi kullanmalıdır android:outlineProvider="background".
WindRider

2
Google'ı bu kadar çok sevmemin bir başka nedeni de bu hatanın neredeyse benim yaşım olması ve hala küçük dünyasında kalması. Google bu konuda cr * ap vermiyor gibi görünüyor))
Farid

1
Ben sadece arka plan şeklindeki topleft ve topRight köşesini yuvarlatılmış olarak ayarladığımda bu yöntemle başarı elde edemiyorum.
Peterdk

@AnuMartin bu bilinen bir sorundur - issuetracker.google.com/issues/37036728
Vadim Kotov

132

Destek kütüphanesinin v21'inde artık bunun bir çözümü var: buna RoundedBitmapDrawable deniyor .

Temel olarak normal bir Çekilebilir gibi, kırpma ile bir köşe yarıçapı vermeniz dışında:

setCornerRadius(float cornerRadius)

Yani, Bitmap srcve bir hedefle başlayarak ImageView, şöyle bir şey olurdu:

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);

3
Çok teşekkürler, işte bir sonraki adım: stackoverflow.com/questions/24878740/…
David d C e Freitas

aslında android.support.v4.graphics.drawable.RoundedBitmapDrawableFactorybunu v4da destekliyor.
deadfish

2
@deadfish evet onun içinde v4destek kitaplığı ancak dek REVISION 21destek kütüphanesinin
tyczj

3
Bu çözüm basit ve günceldir. En az miktarda kod gerektirir ve büyük bir genişletilebilirliğe sahiptir. Yerel dosyadan alınan resimlerle, önbelleğe alınabilir önbellekte ve hatta Volley'in NetworkImageView ile çalışabilir. @Jonik'in de belirttiği gibi, bugünlerde bunun kabul edilen cevap olması gerektiğine katılıyorum.
katie

2
Talihsiz bir şekilde çalışmıyor scaleType centerCrop(destek kütüphanesi v25.3.1)
rocknow

67

Özel ImageView tarafından yaptım:

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

Nasıl kullanılır:

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

Çıktı:

resim açıklamasını buraya girin

Umarım bu sana yardımcı olur.


Bu görüntü bulanıklaştırır
Amit Hooda

2
android ile bile çalışır: scaleType = "centerCrop", basit, yeni bitmap oluşturmaz. Teşekkürler!
ernazm

1
@Hiren Bu çözüm, arka plan görüntüsü olan ImageView için iyi çalışır. Ancak, yalnızca arka plan rengine sahip ve Görüntü içermeyen ImageViews için çalışmaz. Bunun neden olduğunu söyleyebilir misiniz lütfen?
user2991413

Canvas.clipPath()java.lang.UnsupportedOperationExceptionbazı durumlarda neden olabilir . Bkz. Stackoverflow.com/questions/13248904/…
Artyom

1
Bu çözüm yalnızca ile ayarlanmış görüntü kümeleri için çalışır android:background, ancak kullanılamaz android:src.
CoolMind

64

Hızlı bir xml çözümü -

<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'da istediğiniz genişliği, yüksekliği ve yarıçapı ve ImageView'da scaleType'ı ayarlayabilirsiniz.

AndroidX ile şunu kullanın: <androidx.cardview.widget.CardView>


4
bu yaklaşım benim durumumda androidx.cardview.widget.CardView ile çalıştı
Ivan

7
Bunun neden daha fazla oyu olmadığından emin değil misiniz? Kanımca kütüphane ve tonlarca boktan kod olmadan en iyi çözüm (her ne kadar benim durumumda centerCrop ölçekleme kullanmış olsam da).
ThemBones

1
Henüz çok fazla oy yok, çünkü bu yeni bir cevap. Ama yakında yükseltmek için + 1'imi koydum! Teşekkürler!
Micer

Ancak, çalışır ama burada görüntü nedeniyle gerilir scaleType="fitXY"ve düzgün görünmüyor @ThemBones
WIZARD

@WIZARD bu yüzden ImageView
Chirag Mittal

57

Her iki yöntemin de çalışan bir çözüm bulmakta çok yardımcı olduğunu gördüm. İşte benim kompozit versiyonum, pikselden bağımsız ve köşelerin geri kalanıyla aynı yarıçapa sahip olan bazı kare köşelere sahip olmanıza izin veriyor (normal kullanım durumu). Yukarıdaki her iki çözüm sayesinde:

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

Ayrıca, ben xml tanımlayabilirsiniz böylece koymak için ImageView overrode. Süper çağrının burada yaptığı mantığın bazılarını eklemek isteyebilirsiniz, ancak benim durumumda yardımcı olmadığı için yorum yaptım.

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

Bu yardımcı olur umarım!



2
ImageView # onDraw () mantığını korumanın basit bir yolu, yuvarlak köşe bitmap'ini ImageView'in çekilebilir değerine ayarlamak ve bitmap'i çizmek için super.onDraw () 'yi bırakmaktır. RoundedCornerImageView sınıfı oluşturdum ve kullanım örneği burada . Kullandığım getRoundedCornerBitmap () öğesinin pikselden bağımsız olmadığını lütfen unutmayın.
umbalaconmeogia

RoundedCornerImageView için teşekkürler. Ben kullandım ama piksel yoğunluğundan bağımsız olacak şekilde değiştirdim.
PacificSky

Umba'nın RoundedCornerImageView kaynak kodu burada: code.google.com/p/android-batsg/source/browse/trunk/…
Bir Yerde

@Caspar Harmer sadece 1 düzenleme iyi çalışıyor ... dört koşul var ... sadece doğru, doğru, yanlış, yanlış ayarlamış gibi değiştiririm, üst köşe yerine alt köşeyi ayarlayacaktır ... aksi halde kod iyi çalışıyor.so squareTL ve squareTR sırasıyla squareBL ve squareBR için koşullardır ... ve bunun tersi de geçerlidir.
TheFlash

48

Yuvarlak görüntü ImageLoader Burada

Oluşturun 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);

Veya PicassoSquare'den kullanıcı kütüphanesi kullanabilirsiniz .

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

Burada RoundedTransformation dosyayı indirebilirsiniz burada


1
Görüntü gösterilmiyor
Amit Thaper

3
Picasso Kütüphanesi, iyi ve uygulanması çok kolay, çok teşekkürler +1
Hitesh

3
Picasso kütüphanesi "yer tutucu" ve "hata" görüntüsünü dönüştürmüyor gibi görünüyor, bu nedenle görüntünüz yüklenemiyorsa (hata) veya başlangıçta (yer tutucu) yüklenmesi biraz zaman alıyorsa görüntüyü yuvarlak bir görüntü olarak göstermez. github.com/square/picasso/issues/337
Pelpotronic

RoundedCornersTransformation da içeren bu kütüphane tarafından diğer faydalı picasso dönüşümleri sağlanmaktadır: github.com/wasabeef/picasso-transformations
Massimo

Univ'de görüntüleri kırpma ile çalışmaz. Görüntü Yükleyici.
Yar

26

Tüm cevaplar benim için sadece yuvarlak köşeler için çok karmaşık göründüğünden, resmin etrafında biraz boşluk olması durumunda XML ile paylaşmaya değer olduğunu düşündüğüm başka bir çözüme geldim:

Şunun gibi şeffaf içeriğe sahip kenarlı bir şekil oluşturun:

<?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> 

Daha sonra bir RelativeLayout'ta önce görüntünüzü ve daha sonra başka bir ImageView ile şeklin üzerindeki aynı konuma yerleştirebilirsiniz. Kapak şeklinin boyutu, kenarlık genişliği miktarına göre daha büyük olmalıdır. Dış yarıçap tanımlandığından daha büyük bir köşe yarıçapı almaya dikkat edin, ancak görüntünüzü kaplayan iç yarıçap.

Umarım birisine de yardımcı olur.

Düzenleme CQM göre göreli bir düzen örneği rica ediyoruz:

<?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>

bu konuyla ilgili daha fazla kodla, özellikle ikinci görüntü görünümünde neler yapıldığını ve "kenarlıklı şekil" xml'nin uygulandığı (src veya arka plan olarak?) burada birkaç soruyu daha ayrıntılı bir şekilde açıklayabilir misiniz? Bu çözümü beğenmek istiyorum çünkü dört köşeyi de bağımsız olarak kontrol etmeme izin verecek
CQM

1
Basit bir cevap gibi görünse de, maalesef istenmeyen yan etki olan "maskelenmiş" görüntü görünümünün etrafına kenar boşluğu ekler.
Abdalrahman Shatou

evet, ancak aynı şey, köşeleri yuvarlatılmış ve saydam arka plana sahip bir PNG-Drawable'a veya tanımlanmamış bir özelliğiniz varsa 9-Patch-Drawable'a dayanan bir ImageView ile de çalışır.
Hıristiyan

Ben de aynısını yapıyorum ve çalışıyor; sadece oryantasyon ve farklı telefon boyutu ile herhangi bir sorun yaratmayacak bilmek ister misiniz?
açık ve ücretsiz

Boyutları birbirine göre tutarsanız, bu bir sorun yaratmamalıdır.
Christian

22

Sürümü ile başlayan 1.2.0-alpha03ve Malzeme Bileşenleri Kütüphanesi yeni vardır ShapeableImageView.

Şöyle bir şey kullanabilirsiniz:

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

ile:

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

Veya programlı olarak:

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

resim açıklamasını buraya girin


Görüntünün arka plan rengi varsa, şu anda yuvarlatılmış köşelerin altına yerleştirilecek arka plan rengini üretir. Bu aynı zamanda görüntüdeki scaleType özelliğini yok sayar.
inokey

14

ImageView uygulamamı (aşağı || yukarı) köşeleri yuvarlatılmış bir widget ile görüntüyü gerekli boyutlara göre boyutlandırır. CaspNZ kod formunu kullanır.

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

    }

}

12
ImageUtilities nereden geliyor?
13:58, JasonWyatt

1
@JasonWyatt aşağıdaki sorrodos yazı bakın
Damjan

12

Son zamanlarda, başka bir yol daha var - Glide'ın Oluşturulmuş API'sını kullanma . Bazı ilk çalışmaları alır, ancak daha sonra gerçek kodu yazdığınız için size Glide tüm gücünü bir şey yapma esnekliği verir, bu yüzden uzun vadede iyi bir çözüm olduğunu düşünüyorum. Artı, kullanımı çok basit ve temiz.

İlk olarak, Glide sürüm 4+ kurulum :

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

Ardından ek açıklama işlemini tetiklemek için Glid'in uygulama modülü sınıfını oluşturun:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

Ardından, işi gerçekten yapan Glide uzantısını oluşturun. İstediğinizi yapmak için özelleştirebilirsiniz:

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

Bu dosyaları ekledikten sonra projenizi oluşturun.

Daha sonra kodunuzda şu şekilde kullanın:

GlideApp.with(this)
        .load(imageUrl)
        .roundedCorners(getApplicationContext(), 5)
        .into(imageView);

RequestOptionsoptions
Params

Bitti. Giriş için teşekkürler.
Efendim Codesalot

.roundedCorners gelmiyor başka bir şey kurmamız gerekiyor mu? Yeniden inşa projesinden sonra bile
Dr. aNdRO

Bu benim için çalıştı, teşekkürler. @GlideExtensionAçıklamalı sınıfı kullanmaktan kaçınmak daha basit buldum ve sadece aynı yerde ( ) .transform(new RoundedCorners(px))olduğu ile gittim . pxint px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
Michael Osofsky

10

Bir Orada serin kütüphanesi size imageviews şekil sağlar.

İşte bir örnek:

<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"/>

Şekil tanımı:

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

Sonuç:

sonuç


1
Bu harika ve çok daha fazlasını yapıyor, örneğin bir sınır ekleyebilir ve herhangi bir şekli kullanabilirsiniz
Adam Kis

8

İmageView'i geçersiz kılan basit bir örnek, daha sonra önizlemek için mizanpaj tasarımcısında da kullanabilirsiniz.

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

Bu hızlı çözüm içindir. Yarıçap tüm köşelerde kullanılır ve bitmap genişliğinin yüzdesine dayanır.

Ben sadece geçersiz setImageDrawablekılındı ​​ve çizilebilir yuvarlak bitmap için destek v4 yöntemini kullandım.

Kullanımı:

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

İmageView ve özel imageView ile önizleme:

resim açıklamasını buraya girin


Bu her durumda işe yarıyor, teşekkürler. Günümü kurtardın.
Mehul Solanki

7

ImageViewKendi yuvarlatılmış dikdörtgeni uzatmalı ve çizmelisin.

Görüntünün etrafında bir çerçeve istiyorsanız, mizanpajdaki görüntü görünümünün üzerine yuvarlatılmış çerçeveyi de ekleyebilirsiniz.

FrameLayoutÖrneğin , orijinal görüntüyü op yapmak için çerçeveyi üzerine getirin . FrameLayoutİrade'nin ilk öğesi, yuvarlaklaştırmak istediğiniz görüntü olacaktır. Ardından ImageViewçerçeveyle bir tane daha ekleyin . İkincisi ImageVieworijinalin üstünde görüntülenir ImageViewve böylece Android içeriğini orijinalin üzerine çizer ImageView.


Teşekkür ederim. Ancak ImageView için sadece setDrawable yöntemi var, ImageView'in Drawable'ı görüntümün içeriğine nasıl ayarlayabilirim ve daha sonra ImageView'in üstüne yuvarlak bir çerçeve yerleştirebilirim?
michael

Üzgünüm, belirsiz oluyordum. Düzende üst üste binmek istedim: böylece (yani) FrameLayoutiçine bir put kullanın ve yuvarlak çerçeveli bir tane ImageViewekleyin ImageView. Bu şekilde birincisi ImageViewseçtiğiniz resmi, ikincisi ImageFrameyuvarlak çerçeveyi görüntüler.
MrSnowflake

Doğru - FrameLayout ile bir görüntüyü / görünümü başka bir görüntüye bindirebilirsiniz. FrameLayout'un android: foreground etiketini de kullanabilirsiniz.
Richard Le Mesurier

7

Romain Guy orada.

Minimize edilmiş sürüm aşağıdaki gibidir.

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

ne yazık ki, işe yarıyor olsa da, buradaki çözümlerin geri kalanı gibi, mevcut olanı kullanmak yerine yeni bir bitmap oluşturur.
android geliştirici

pek sayılmaz. bitmapRounded tekrar tekrar kullanılır. çizilebilir tuvale erişiminiz varsa, yeni bir bitmap oluşturmak yerine doğrudan çizim yöntemini kullanabilirsiniz.
Alex

bunu nasıl yaptın? herhangi bir özel çekilebilir ve sadece tek bir bitmap işlemek ve işlemin sonunda setImageBitmap kullanın varsayalım. böyle bir şeyi nasıl başarabilirim?
android geliştirici 13


her ikisi de bitmap'i değiştirmez, ancak özel bir çekilebilir ve özel bir görüntüleme kullanarak sarın. bu benim sorduğum şey değil. Bitmap'i nasıl değiştireceğinizi sordum.
android geliştirici

7

Bu saf xml çözümü benim durumumda yeterince iyiydi. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

DÜZENLE

Kısacası cevap:

/ Res / drawable klasöründe bir frame.xml dosyası oluşturun. İçinde, köşeleri yuvarlatılmış basit bir dikdörtgen ve şeffaf bir merkez tanımlarız .

<?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>

Düzen dosyanıza iç içe bir FrameLayout'un yanı sıra standart bir ImageView içeren bir LinearLayout eklersiniz. FrameLayout, yuvarlatılmış köşelerin yanılsamasını vermek için dolgu ve özel çekilebilir kullanır.

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

güzel bir fikir, bunu un-Even ImageView köşeleri göstermek için kullandım
Gal Rom

6

Yukarıdaki George Walters II'den aksesuarlar, sadece cevabını aldım ve köşeleri farklı şekilde yuvarlamayı desteklemek için biraz uzattım. Bu biraz daha optimize edilebilir (bazı hedef rektleri çakışır), ancak bir sürü değil.

Bu iş parçacığının biraz eski olduğunu biliyorum, ancak Android'de ImageViews köşelerini yuvarlaklaştırmak için Google'daki sorgular için en iyi sonuçlardan biri.

/**
 * 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;
}

Yoğunluk çarpanı eklemek ve tek tek yuvarlanan köşeler için destek eklemek için +1. Çözümün işe yaramadığı için aslında çözümü en üstte kullandım - ama çok yardımcı oldu! Aşağıdaki kompozit
çözümüme

6

imageViewAşağıdaki gibi bir şekil uygulayın:

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

arkadaşınıza yardımcı olabilir.


6

Neden kırpma yapmıyorsunuz draw()?

İşte benim çözümüm:

  • RelativeLayout'u kırpma ile genişletme
  • ImageView (veya diğer görünümleri) mizanpaja yerleştirin:

Kod:

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

}

1
Bu yaklaşımı seviyorum. Kendi RoundImageView'ımı oluşturmak için kullandım. Bunun için teşekkürler.
Pascal

Hardward hızlanma açıkken bu işe yaramıyor, değil mi? Kolay bir çözüm görmedim ...
secureboot

Bunu nasıl yapacağınızı, sonucun çekilebilir olarak göstererek, içeriğin etrafına bir anahat (AKA konturu) ekleme ve ayrıca köşelerin sadece bazılarını yuvarlama yeteneğine sahip olabileceğinizi gösterebilir misiniz?
android geliştirici

5

Aşağıda, içine yerleştirilmiş alt nesnelerin etrafına yuvarlatılmış bir dikdörtgen çizen yuvarlak bir dikdörtgen düzen nesnesi oluşturulur. Ayrıca mizanpaj xml dosyalarını kullanmadan programlı olarak görünümlerin ve mizanpajların nasıl oluşturulacağını gösterir.

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 mizanpaj nesnesi için sınıf burada tanımlandığı gibidir:

/**
 *  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;
 }

}

5

Kotlin

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)

ImageViewDairesel yapmak için aşağıdakilerle değiştirebiliriz cornerRadius:

rounded.isCircular = true

4

İlk cevaba çok teşekkür ederim. Burada dikdörtgen bir görüntüyü kare olana (ve yuvarlatılmış) dönüştürmek için değiştirilmiş versiyon ve dolgu rengi parametre olarak geçiriliyor.

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 kullanıyorsanız bu yardımcı olacaktır:

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

Glide sürüm 4 ve üstü kullanıyorsanız --- RequestOptions requestOptions = new RequestOptions (); requestOptions = requestOptions.transforms (yeni CenterCrop (), yeni RoundedCorners (16)); Glide.with (itemView.getContext ()) .load (item.getImage ()) .apply (requestOptions) .into (mProgramThumbnail);
B.shruti

3

resminiz internette ise en iyi yol kayma kullanmaktır RoundedBitmapDrawableFactory(API 21'den - ancak destek kitaplığında kullanılabilir) şöyle:

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

Bu zarif bir API, ancak .centerInside eksik gibi görünüyor, bu nedenle belki de bu tür parametreleri tanımlamak için xml kullanmak daha iyidir
carl

Bu, görüntü kaynaklarda olduğunda ve kullanmanız gerektiğinde de kullanışlıdırcenterCrop
Artyom

3

yalnızca ImageViewmizanpajınızda kullanabilir ve kullanarak glide, bu yöntemi kullanarak yuvarlak köşeler uygulayabilirsiniz.

önce gradle yazmanızda,

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

köşeleri yuvarlatılmış görüntü için,

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

çağrı yöntemi:

loadImageWithCorners("your url","your imageview");

Bu, HTTP isteği yoluyla soru yüklemek için bir kitaplık ekleyecektir.
creativecreatorormaybenot

Hangi kütüphane yüklenecek? Görüntü yükleme için glide ve snippet'i tamamen glide yöntemlerine ve sınıflarına göre kullanabilirsiniz. Başka bir kütüphanenin eklenmesine gerek yok
Deep Patel

Glide, öncelikle HTTP üzerinden görüntü yüklemek için bir kitaplıktır, ancak OP bir ImageView.
creativecreatorormaybenot

2

Burada yönlendirilen sorunun cevabı: "Android'de dairesel bir ImageView nasıl oluşturulur?"

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

Kayma kütüphanesi ve RoundedBitmapDrawableFactory sınıfının yardımıyla başarmak kolaydır. Dairesel yer tutucu görüntü oluşturmanız gerekebilir.

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

2

Glide ve Kotlin'i kullananlar için, bunu genişleterek RequestBuilder

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

ve olarak kullanın;

 GlideApp.with(context)
            .load(url)
            .roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
            .into(imgView)

.roundedCorners gelmiyor başka bir şey kurmamız gerekiyor mu?
Dr. aNdRO

roundCornersyukarıdaki gibi uzantı fonksiyonunu eklediniz mi? @ Dr.aNdRO
dgngulcan

Lütfen uygun bir örnek veriniz! Bu cevap kafa karıştırıcı!
Junia Montana
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.