Como criar um ImageView com cantos arredondados?

573

No Android, um ImageView é um retângulo por padrão. Como faço para torná-lo um retângulo arredondado (recorte todos os quatro cantos do meu Bitmap para serem retângulos arredondados) no ImageView?

Michael
fonte
Isso pode ser útil stackoverflow.com/questions/26850780/…
Mangesh
Escondido abaixo mais velhos, respostas mais complicado é o que eu acho que deve ser a resposta aceita agora: RoundedBitmapDrawable , acrescentou, em v4 revisão Biblioteca de suporte 21.
Jonik
Você pode fazê-lo maneira mais fácil usando apenas o CardView com um interior ImageView - olhe o exemplo aqui stackoverflow.com/a/41479670/4516797
Taras Vovkovych
Esta biblioteca é muito útil.
grrigore
Verifique isso agora, temos ShapeableImageViewque fazer uma imagem circular ou arredondadaView stackoverflow.com/a/61086632/7666442
Nilesh Rathod

Respostas:

545

Isso é bastante tardio em resposta, mas para qualquer pessoa que esteja procurando por isso, você pode fazer o seguinte código para arredondar manualmente os cantos das suas imagens.

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

Este não é o meu código, mas eu o usei e funciona maravilhosamente. Usei-o como auxiliar dentro de uma classe ImageHelper e estendi-o um pouco para passar a quantidade de difusão necessária para uma determinada imagem.

O código final fica assim:

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

Espero que isso ajude alguém!

George Walters II
fonte
4
Ele não funciona para todos os dispositivos. Preciso mudar em algum lugar?
Spring Breaker
7
Demora quase 0,03 segundo para fazer isso em uma imagem de 200 * 200, então acho que essa não é a melhor solução.
21413 Jacky
2
Arredonda apenas os cantos superior esquerdo e superior direito. Por quê ?
Prateek
1
@ solução vinc3m1 aqui github.com/makeramen/RoundedImageView funciona muito bem! também ver a sua resposta ( stackoverflow.com/a/15032283/2048266 )
nommer
16
Não está funcionando bem ao tentar definir o tipo de escalonamento do imageview, apenas o fitXY está funcionando, centerCrop e outros estão mostrando resultados imprevisíveis, alguém aqui tem os mesmos problemas?
Shivansh
211

Enquanto a resposta acima funciona, Romain Guy (um desenvolvedor central do Android) mostra um método melhor em seu blog que usa menos memória usando um sombreador que não cria uma cópia do bitmap. A essência geral da funcionalidade está aqui:

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

As vantagens disso sobre outros métodos é que:

  • não cria uma cópia separada do bitmap, que usa muita memória com imagens grandes [vs a maioria das outras respostas aqui]
  • suporta antialisasing [vs clipPath method]
  • suporta alpha [método xfermode + porterduff]
  • suporta aceleração de hardware [vs clipPath method]
  • desenha apenas uma vez na tela [métodos xfermode e clippath]

Eu criei um RoundedImageView com base nesse código que agrupa essa lógica em um ImageView e adiciona ScaleTypesuporte adequado e uma borda arredondada opcional.

vinc3m1
fonte
no seu / example / res / layout / rounded_item.xml por que você especifica uma imagem src quando todas as suas fontes são codificadas? Boa demonstração, um exagero.
Alguém em algum lugar
sua amostra tem um sério problema de falta de memória, assim como a amostra original de Romain Guy. Ainda não sei o que causa isso, mas, assim como o código dele, isso é realmente algo difícil de encontrar. Se você não conseguir ver uma falha no aplicativo por causa do OOM, poderá girá-lo várias vezes até que ocorra (depende do seu dispositivo, ROM, etc ...). Eu relatei sobre isso no passado aqui: stackoverflow.com/questions/14109187/…
desenvolvedor Android
1
Ninguém mais está relatando o problema de falta de memória; portanto, deve estar fazendo algo fora do código incorreto. O exemplo contém corretamente um conjunto limitado de bitmaps no adaptador sem recriá-los sempre que uma exibição é desenhada. O exemplo mostrado aqui é um trecho do método draw () no Drawable, que usa a referência ao bitmap original que contém e funciona corretamente. Ele é não significava para mudar o bitmap original, mas apenas torná-lo com cantos arredondados. O recorte central também funciona bem no exemplo.
Vinc3m1
1
Se você pode fornecer capturas de tela ou dispositivos onde não funciona, ou até oferecer uma solicitação de correção e recebimento, isso seria mais produtivo. Testei a rotação várias vezes nos meus dispositivos e a memória permanece a mesma.
vinc3m1
11
Observe que não funcionará se o tamanho da imagem estiver acima de 2048 pixels. O shader não suporta uma textura para ser maior que isso.
Gábor
209

Outra maneira fácil é usar um CardView com o raio do canto e um ImageView dentro:

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

insira a descrição da imagem aqui

Taras Vovkovych
fonte
5
Parece uma boa solução alternativa. Mas não recorta imagens em pré-pirulitos.
Nikolai #
1
E se quisermos apenas o raio nos cantos superior esquerdo e superior direito e nem todos os cantos?
Pratik Singhal 22/10
3
Maneira muito simples e inteligente de aplicar a borda da curva em qualquer visualização.
AMI CHARADAVA
1
Boa solução, mas a elevação é suportado apenas em nível API 21 e acima
Saad Bilal
1
Para desativar o aplicativo cartão de uso elevação: cardElevation = "0dp" (não android: elevação)
Johnny Cinco
150

O recorte para formas arredondadas foi adicionado à Viewclasse na API 21.

Apenas faça o seguinte:

  • Crie um desenho de forma arredondada, algo como isto:

res / drawable / round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>
  • Defina o drawable como plano de fundo do seu ImageView: android:background="@drawable/round_outline"
  • De acordo com esta documentação , tudo que você precisa fazer é adicionarandroid:clipToOutline="true"

Infelizmente, há um erro e esse atributo XML não é reconhecido. Felizmente, ainda podemos configurar o recorte em Java:

  • Na sua atividade ou fragmento: ImageView.setClipToOutline(true)

Aqui está como será:

insira a descrição da imagem aqui

Nota:

Este método funciona para qualquer forma desenhável (não apenas arredondada). Ele recortará o ImageView no contorno de forma que você definiu no seu xml Drawable.

Nota especial sobre o ImageViews

setClipToOutline()só funciona quando o plano de fundo da vista é definido como uma forma desenhável. Se essa forma de plano de fundo existir, o View tratará o contorno da forma como as bordas para fins de recorte e sombreamento.

Isso significa que, se você deseja usar setClipToOutline()para arredondar os cantos em um ImageView, sua imagem deve ser definida usando em android:srcvez de android:background(já que o plano de fundo deve ser definido como sua forma arredondada). Se você DEVE usar o plano de fundo para definir sua imagem em vez de src, pode usar esta solução alternativa:

  • Crie um layout e defina seu plano de fundo para o formato que você pode desenhar
  • Enrole esse layout em torno do seu ImageView (sem preenchimento)
  • O ImageView (incluindo qualquer outra coisa no layout) agora será exibido com formato de layout arredondado.
fome
fonte
10
Erro: (x) Nenhum identificador de recurso encontrado para o atributo 'clipToOutline' no pacote 'android'
Anu Martin
7
Em vez disso android:clipToOutline, é preciso usar android:outlineProvider="background".
WindRider 26/01
2
Outra razão pela qual eu "amo" tanto o Google é que esse bug tem quase a minha idade e ainda reside em seu pequeno mundo. O Google parece não dar a mínima para isso)))
Farid
1
Parece que não tenho sucesso com esse método quando apenas defino topleft e topRight corner na forma de plano de fundo como arredondado.
22619 Peterdk
@AnuMartin, este é um problema conhecido - issuetracker.google.com/issues/37036728
Vadim Kotov
132

Na v21 da biblioteca de Suporte, agora existe uma solução para isso: ela se chama RoundedBitmapDrawable .

É basicamente como um Drawable normal, exceto que você fornece um raio de canto para o recorte com:

setCornerRadius(float cornerRadius)

Então, começando com Bitmap srce um alvo ImageView, seria algo como isto:

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
tyczj
fonte
3
Grandes graças, aqui é o próximo passo: stackoverflow.com/questions/24878740/...
David d C E Freitas
na verdade não há android.support.v4.graphics.drawable.RoundedBitmapDrawableFactoryassim v4também suporta.
deadfish
2
@deadfish sim sua em v4biblioteca de apoio, mas não até REVISION 21da biblioteca de suporte
tyczj
3
Esta é uma solução simples e atualizada. Requer a menor quantidade de código e possui grande extensibilidade. Pode trabalhar com imagens de arquivo local, drawable em cache ou mesmo com o NetworkImageView da Volley. Concordo plenamente que essa seja a resposta aceita hoje em dia, como apontou @Jonik.
22817 katie
2
Unfortutately não funciona com scaleType centerCrop(biblioteca de suporte v25.3.1)
rocknow
67

Eu fiz pelo 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);
    }
}

Como usar:

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

Resultado:

insira a descrição da imagem aqui

Espero que isto te possa ajudar.

Hiren Patel
fonte
isso faz com que o desfoque de imagem
Amit Hooda
2
funciona mesmo com o android: scaleType = "centerCrop", simples, não cria novo bitmap. Obrigado!
Ernazm #
1
@Hiren Esta solução funciona bem para o ImageView com uma imagem de fundo. Mas não funciona para ImageViews, que tem apenas a cor de fundo e nenhuma imagem. Pode me dizer por que isso está acontecendo?
user2991413
Canvas.clipPath()pode causar java.lang.UnsupportedOperationExceptionem alguns casos. Veja stackoverflow.com/questions/13248904/…
Artyom
1
Esta solução funciona apenas para imagens definidas com android:background, mas não android:src.
CoolMind 20/09/2018
65

Uma solução xml rápida -

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

Você pode definir a largura, altura e raio desejados no CardView e scaleType no ImageView.

Com o AndroidX, use <androidx.cardview.widget.CardView>

Chirag Mittal
fonte
4
esta abordagem funcionou no meu caso com androidx.cardview.widget.CardView
Ivan
7
Não sabe por que isso não tem mais votos positivos? Na minha opinião, a melhor solução sem bibliotecas e toneladas de código de merda (embora eu tenha usado o dimensionamento centerCrop no meu caso).
ThemBones 29/03/19
1
Ainda não há muitos votos positivos, porque é uma nova resposta. Mas eu coloquei meu +1 para subir em breve! Obrigado!
Micer
no entanto, ele funciona, mas aqui a imagem será esticada por causa scaleType="fitXY"e não parece adequada @ThemBones
WIZARD
@WIZARD é por isso que eu mencionei que você pode definir o seu ScaleType desejado no ImageView
Chirag Mittal
57

Eu descobri que ambos os métodos eram muito úteis para encontrar uma solução funcional. Aqui está minha versão composta, que é independente de pixels e permite que você tenha alguns cantos quadrados, com o restante dos cantos tendo o mesmo raio (que é o caso de uso usual). Agradecemos às duas soluções acima:

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

Além disso, eu substituí o ImageView para colocar isso para que eu pudesse defini-lo em xml. Você pode adicionar algumas das lógicas que a chamada super faz aqui, mas eu as comentei, pois não é útil no meu caso.

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

Espero que isto ajude!

Caspar Harmer
fonte
4
incrível, especialmente estendendo o ImageView
Someone Somewhere
2
Uma maneira simples de manter a lógica do ImageView # onDraw () é definir o bitmap do canto arredondado na gaveta do ImageView e deixar o super.onDraw () para desenhar o bitmap. Eu criei uma classe RoundedCornerImageView , e seu exemplo de uso está aqui . Observe que o getRoundedCornerBitmap () que eu usei não é independente de pixel.
Umbalaconmeogia #
Obrigado pelo RoundedCornerImageView. Eu usei, mas modifiquei para ser independente da densidade de pixels.
PacificSky
O código-fonte do RoundedCornerImageView da umba está aqui: code.google.com/p/android-batsg/source/browse/trunk/…
Alguém em algum lugar
@ Caspar Harmer funcionando bem apenas 1 edição ... existem quatro condições ... basta alterá-las como se eu definir verdadeiro, verdadeiro, falso, falso, ele definirá o canto inferior em vez do canto superior ... caso contrário, o código está funcionando bem. e squareTR são condições para squareBL e squareBR respectivamente .. e vica-versa.
TheFlash 15/10/2015
48

Imagem arredondada Usando ImageLoader aqui

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

Ou você pode usar a PicassoBiblioteca da Square.

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

você pode baixar o arquivo RoundedTransformation aqui aqui

shailesh
fonte
1
Não exibir imagem
Amit Thaper
3
A única Picasso Biblioteca é bom, e muito fácil de implementar, muito obrigado +1
Hitesh
3
A biblioteca do Picasso parece não transformar a imagem "espaço reservado" e "erro"; portanto, se sua imagem falhar ao carregar (erro) ou demorar um pouco para carregar inicialmente (espaço reservado), ela não exibirá a imagem como uma imagem arredondada. github.com/square/picasso/issues/337
Pelpotronic
Outras transformações úteis do picasso são fornecidas por esta biblioteca, que também contém uma RoundedCornersTransformation: github.com/wasabeef/picasso-transformations
Massimo
Não funciona com o corte de imagens no Univ. Carregador de imagens.
Yar
26

Como todas as respostas me pareciam muito complicadas apenas para os cantos arredondados, pensei e cheguei a outra solução que acho que vale a pena compartilhar, apenas com XML, caso você tenha algum espaço em torno da imagem:

Crie uma forma com borda com conteúdo transparente como este:

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

Em um RelativeLayout, você pode primeiro colocar sua imagem e, em seguida, no mesmo local acima da forma com outro ImageView. A forma da capa deve ser maior em tamanho pela quantidade da largura da borda. Tenha cuidado com um raio de canto maior, pois o raio externo é definido, mas o raio interno é o que cobre sua imagem.

Espero que ajude alguém também.

Edite conforme a solicitação do CQM o exemplo de layout relativo:

<?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>
cristão
fonte
você pode elaborar mais sobre isso com mais código, especialmente o que está sendo feito com a segunda visualização de imagem e onde o xml de "forma com borda" está sendo aplicado (como src ou como plano de fundo?) várias perguntas aqui. Eu quero gostar desta solução, pois ela permitirá que eu controle todos os quatro cantos de forma independente
CQM
1
Embora pareça ser uma resposta simples, infelizmente adiciona margem à exibição de imagem "mascarada", o que é um efeito colateral indesejável.
Abdalrahman Shatou
sim, mas o mesmo funciona com um ImageView baseado em um PNG-Drawable com cantos arredondados e fundo transparente ou um 9-Patch-Drawable se você tiver um aspecto indefinido.
Christian
Estou fazendo da mesma maneira, e está funcionando; só quer saber se isso não criará nenhum problema com a orientação e o tamanho do telefone diferente?
aberto e gratuito
Se você mantiver as dimensões relativas uma à outra, isso não deverá criar um problema.
Christian
22

Começando com a versão 1.2.0-alpha03da Biblioteca de componentes de materiais, há o novoShapeableImageView .

Você pode usar algo como:

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

com:

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

Ou programaticamente:

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

insira a descrição da imagem aqui

Gabriele Mariotti
fonte
Se a imagem tiver cor de fundo, atualmente ela produzirá a cor de fundo para aparecer sob os cantos arredondados. Isso também ignora a propriedade scaleType na imagem.
inokey
14

Minha implementação do ImageView com widget de cantos arredondados, que (para baixo || para cima) dimensiona a imagem para as dimensões necessárias. Ele utiliza o formulário de código 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
fonte
12
De onde vem o ImageUtilities?
JasonWyatt
1
@JasonWyatt veja sorrodos post abaixo
Damjan
12

Recentemente, existe outra maneira - usar a API Gerada da Glide . É preciso algum trabalho inicial, mas, em seguida, oferece todo o poder do Glide com a flexibilidade de fazer qualquer coisa, porque você escreve o código real, então acho que é uma boa solução a longo prazo. Além disso, o uso é muito simples e arrumado.

Primeiro, configure o Glide versão 4+:

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

Em seguida, crie a classe do módulo de aplicativo do Glid para acionar o processamento da anotação:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

Em seguida, crie a extensão Glide, que realmente faz o trabalho. Você pode personalizá-lo para fazer o que quiser:

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

Depois de adicionar esses arquivos, crie seu projeto.

Em seguida, use-o no seu código assim:

GlideApp.with(this)
        .load(imageUrl)
        .roundedCorners(getApplicationContext(), 5)
        .into(imageView);
Sir Codesalot
fonte
Não se esqueça de adicionar um espaço entre RequestOptionse optionsem params
StevenTB
Feito. Obrigado pela contribuição.
precisa saber é o seguinte
.roundedCorners não estão chegando, precisamos configurar mais alguma coisa? Mesmo após a reconstrução do projeto
Dr. aNdRO
Isso funcionou para mim, obrigado. Achei mais simples evitar o uso da @GlideExtensionclasse anotada e apenas segui .transform(new RoundedCorners(px))onde pxé o mesmo ( int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));).
Michael Osofsky
10

Existe uma biblioteca interessante que permite moldar visualizações de imagens.

Aqui está um exemplo:

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

Definição da forma:

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

Resultado:

resultado

grrigore
fonte
1
Isso é ótimo, e faz muito mais, como você pode adicionar uma borda e usar toda a forma
Adam Kis
8

Aqui está um exemplo simples de substituição do imageView; você também pode usá-lo no designer de layout para visualizar.

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

Isto é para solução rápida. O raio é usado em todos os cantos e baseia-se na porcentagem da largura do bitmap.

Acabei de substituir setImageDrawablee usei o método support v4 para desenhar bitmap arredondado.

Uso:

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

Visualização com imageView e imageView personalizado:

insira a descrição da imagem aqui

peixe morto
fonte
Isso está funcionando em todas as situações, obrigado. Você salvou o meu dia.
Mehul Solanki
7

Você deve estender ImageViewe desenhar seu próprio retângulo arredondado.

Se você deseja um quadro ao redor da imagem, também pode sobrepor o quadro arredondado na parte superior da visualização da imagem no layout.

[editar] Sobreponha o quadro à imagem original, usando a, FrameLayoutpor exemplo. O primeiro elemento do FrameLayoutserá a imagem que você deseja exibir arredondada. Em seguida, adicione outro ImageViewcom o quadro. O segundo ImageViewserá exibido em cima do original ImageViewe, portanto, o Android desenhará seu conteúdo acima do original ImageView.

MrSnowflake
fonte
Obrigado. Mas existe apenas o método setDrawable para o ImageView, como posso definir o DrawDrawable do ImageView para o conteúdo da minha imagem e sobrepor um quadro arredondado na parte superior do ImageView?
22610 Michael
Me desculpe, eu não estava sendo clara. Eu quis dizer sobrepor no layout: assim (ou seja), use um FrameLayoutcoloque um ImageViewnele e adicione outro ImageViewcom o quadro arredondado. Dessa forma, a primeira ImageViewexibirá a imagem selecionada e a segunda ImageFrameexibirá o quadro arredondado.
MrSnowflake
Correto - com o FrameLayout, você pode sobrepor uma imagem / exibição com outra. Você também pode usar a tag android: foreground do FrameLayout.
Richard Le Mesurier 29/11
7

Romain Guy é onde está.

Versão reduzida da seguinte forma.

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
fonte
infelizmente, embora funcione, mas, assim como o restante das soluções aqui, ele cria um novo bitmap em vez de usar o atual.
desenvolvedor android
Na verdade não. bitmapRounded seria usado repetidamente. se você teve acesso à tela de desenho, pode usar o método draw diretamente em vez de gerar um novo bitmap.
Alex #
como você faz isso? suponha que eu não use nenhum drawable especial e apenas lide com um único bitmap e use setImageBitmap no final do processo. como eu conseguiria uma coisa dessas?
desenvolvedor android
confira o exemplo de romain guy curious-creature.org/2012/12/11/… e exemplo de aplicativo docs.google.com/file/d/0B3dxhm5xm1sia2NfM3VKTXNjUnc/edit
Alex
ambos não alteram o bitmap, mas envolvem-no usando um drawable personalizado e uma visualização de imagem personalizada. não é isso que eu perguntei. Eu perguntei como você altera o próprio bitmap.
desenvolvedor android
7

Esta solução xml pura foi boa o suficiente no meu caso. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

EDITAR

Aqui está a resposta em poucas palavras:

Na pasta / res / drawable, crie um arquivo frame.xml. Nele, definimos um retângulo simples com cantos arredondados e um centro transparente .

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

No seu arquivo de layout, você adiciona um LinearLayout que contém um ImageView padrão, bem como um FrameLayout aninhado. O FrameLayout usa preenchimento e a gaveta personalizada para dar a ilusão de cantos arredondados.

<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
fonte
boa idéia, eu usei-o para mostrar uma cantos ImageView un-Even
Gal Rom
6

Adereços para George Walters II acima, eu apenas peguei a resposta dele e a estendi um pouco para apoiar as curvas individuais de maneira diferente. Isso pode ser otimizado um pouco mais (alguns dos rects de destino se sobrepõem), mas não muito.

Sei que esse tópico é um pouco antigo, mas é um dos principais resultados de consultas no Google sobre como arredondar os cantos do ImageViews no 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
fonte
+1 para adicionar o multiplicador de densidade e adicionar suporte para cantos arredondados individualmente. Na verdade, usei a solução na parte superior, pois sua solução não funcionou completamente - mas foi muito útil! Veja minha solução composta abaixo:
Caspar Harmer
6

Aplique uma forma ao seu imageViewcomo abaixo:

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

pode ser útil para você amigo.

jigar
fonte
6

Por que não recortar draw()?

Aqui está a minha solução:

  • Estenda RelativeLayout com recorte
  • Coloque o ImageView (ou outros modos de exibição) no layout:

Código:

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
fonte
1
Eu gosto dessa abordagem. Usei-o para criar meu próprio RoundImageView. Obrigado por isso.
Pascal
Isso não funciona com a aceleração acelerada ativada, correto? Eu não vi uma solução fácil ...
secureboot
Você pode mostrar como fazê-lo, tendo o resultado como um desenhável, tem a capacidade de adicionar um contorno (AKA stroke) ao redor do conteúdo e também a capacidade de fazer apenas alguns dos cantos a serem arredondados?
desenvolvedor android
5

A seguir, cria um objeto de layout de retângulo arredondado que desenha um retângulo arredondado em torno de qualquer objeto filho que é colocado nele. Também demonstra como criar visualizações e layouts programaticamente sem usar os arquivos xml de layout.

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

A classe para o objeto de layout RoundedRectangle é como definida aqui:

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

}
Danny Remington - OMS
fonte
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)

Para fazer ImageViewcircular, podemos mudar cornerRadiuscom:

rounded.isCircular = true
Vahid
fonte
4

Muito obrigado à primeira resposta. Aqui está a versão modificada para converter uma imagem retangular em quadrada (e arredondada) e a cor do preenchimento está sendo passada como parâmetro.

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;
}
mkm
fonte
4

Se você estiver usando a Biblioteca Glide, isso seria útil:

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
fonte
Se estiver usando o Glide versão 4 e superior, use --- RequestOptions requestOptions = new RequestOptions (); requestOptions = requestOptions.transforms (new CenterCrop (), new RoundedCorners (16)); Deslize.com (itemView.getContext ()) .load (item.getImage ()) .apply (requestOptions) .into (mProgramThumbnail);
B.shruti
3

se sua imagem estiver na internet, a melhor maneira é usar o glide e RoundedBitmapDrawableFactory(da API 21 - mas disponível na biblioteca de suporte) assim:

 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);
    }
});
Amir Ziarati
fonte
Este é um elegante api, no entanto, .centerInside parece estar faltando, portanto, talvez seja melhor usar o XML para definir tais parâmetros
carl
Isso também é útil quando a imagem é em recursos e você precisa usarcenterCrop
Artyom
3

você pode usar apenas ImageViewno layout e no uso glide, pode aplicar cantos arredondados usando esse método.

primeiro na sua escrita gradle,

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

para imagem com cantos arredondados,

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

método de chamada:

loadImageWithCorners("your url","your imageview");
Deep Patel
fonte
Isso adicionará uma biblioteca para carregar imagens através da solicitação HTTP, o que não é relevante para a pergunta.
creativecreatorormaybenot
Qual biblioteca será carregada? Para o carregamento de imagens, você pode usar o glide e o snippet puramente com base nos métodos e classes de glide em si. Há outras necessidades da biblioteca a ser adicionado
Profundo Patel
O Glide é uma biblioteca principalmente para carregar imagens por HTTP, mas o OP queria saber como arredondar os cantos de um ImageView.
Creativecreatorormaybenot
2

Responda à pergunta que é redirecionada aqui: "Como criar um ImageView circular no 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;
}
Andrey
fonte
2

Com a ajuda da biblioteca glide e da classe RoundedBitmapDrawableFactory , é fácil de obter. Pode ser necessário criar uma imagem de espaço reservado circular.

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

Para aqueles que usam Glide e Kotlin, você pode conseguir isso estendendo RequestBuilder

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

e use como;

 GlideApp.with(context)
            .load(url)
            .roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
            .into(imgView)
dgngulcan
fonte
.roundedCorners não vem, precisamos configurar mais alguma coisa?
Dr. aNdRO
você adicionou a função de extensão roundCornerscomo acima? @ Dr.aNdRO
dgngulcan
Por favor, forneça um exemplo adequado! Esta resposta é confusa!
Junia Montana 27/01