web-dev-qa-db-fra.com

Comment faire un ImageView avec des coins arrondis?

Sous Android, un ImageView est un rectangle par défaut. Comment puis-je en faire un rectangle arrondi (couper les 4 coins de mon bitmap pour qu'ils soient des rectangles arrondis) dans ImageView? 

482
michael

La réponse est assez tardive, mais si vous recherchez une solution, vous pouvez utiliser le code suivant pour arrondir manuellement les angles de vos images.

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

Ce n'est pas mon code, mais je l'ai utilisé et cela fonctionne à merveille. Je l'ai utilisé en tant qu'assistant dans une classe ImageHelper et l'ai étendu un peu pour indiquer la quantité de dégradé dont j'ai besoin pour une image donnée.

Le code final ressemble à ceci:

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

J'espère que cela aide quelqu'un!

525
George Walters II

Alors que la réponse ci-dessus fonctionne, Romain Guy (un développeur principal pour Android) montre une meilleure méthode dans son blog qui utilise moins de mémoire en utilisant un shader ne créant pas de copie du bitmap. L'essentiel général de la fonctionnalité est ici:

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

Les avantages de cette méthode par rapport aux autres méthodes sont les suivantes:

  • ne crée pas une copie séparée du bitmap, qui utilise beaucoup de mémoire avec de grandes images [vs la plupart des autres réponses ici]
  • prend en charge antialisasing [méthode vs clipPath]
  • supporte alpha [vs méthode xfermode + porterduff]
  • prend en charge l'accélération hardware [méthode vs clipPath]
  • seul dessine une fois sur la toile [vs méthodes xfermode et clippath]

J'ai créé un RoundedImageView basé sur ce code qui englobe cette logique dans un ImageView et ajoute le support approprié ScaleType et une bordure arrondie optionnelle.

196
vinc3m1

Un autre moyen simple consiste à utiliser un CardView avec le rayon de coin et un ImageView à l'intérieur:

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

 enter image description here

122
Taras Vovkovych

Dans la v21 de la bibliothèque Support, il existe maintenant une solution à cela: elle s'appelle RoundedBitmapDrawable .

C'est fondamentalement comme un Drawable normal sauf que vous lui donnez un rayon de coin pour le découpage avec:

setCornerRadius(float cornerRadius)

Donc, en commençant par Bitmap src et une cible ImageView, cela ressemblerait à ceci:

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

Le découpage en formes arrondies a été ajouté à la classe View dans API 21.

Faites juste ceci:

  • Créez une forme arrondie pouvant être dessinée, comme ceci:

res/drawable/round_outline.xml

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="rectangle">
    <corners Android:radius="10dp" />
    ...
</shape>
  • Définissez le dessinable comme arrière-plan de votre ImageView: Android:background="@drawable/round_outline"
  • Selon cette documentation , tout ce que vous avez à faire est d’ajouter Android:clipToOutline="true"

Malheureusement, il y a un bogue et cet attribut XML n'est pas reconnu. Heureusement, nous pouvons toujours configurer la découpe en Java:

  • Dans votre activité ou fragment: ImageView.setClipToOutline(true)

Voici à quoi cela ressemblera:

enter image description here

Remarque:

Cette méthode fonctionne pour toute forme dessiné (pas seulement arrondie). Il visionnera ImageView selon le contour de forme défini dans votre fichier XML Drawable.

Note spéciale sur ImageViews

setClipToOutline() ne fonctionne que lorsque l'arrière-plan de la vue est défini sur une forme pouvant être dessinée. Si cette forme d'arrière-plan existe, View considère le contour de la forme comme des bordures à des fins de découpage et d'ombrage.

Cela signifie que si vous souhaitez utiliser setClipToOutline() pour arrondir les angles d'un ImageView, votre image doit être définie avec Android:src au lieu de Android:background (car l'arrière-plan doit être défini sur votre forme arrondie). Si vous DEVEZ utiliser l’arrière-plan pour définir votre image au lieu de src, vous pouvez utiliser cette solution de contournement:

  • Créer une mise en page et définir son arrière-plan sur votre forme dessinable
  • Enroulez cette disposition autour de votre ImageView (sans remplissage)
  • ImageView (y compris tout ce qui existe dans la mise en page) s'affichera maintenant avec une forme de mise en page arrondie.
80
hungryghost

J'ai trouvé que les deux méthodes étaient très utiles pour trouver une solution efficace. Voici ma version composite, indépendante du pixel, qui vous permet d’avoir des coins carrés, le reste des coins ayant le même rayon (ce qui est le cas d’utilisation habituel). Grâce aux deux solutions ci-dessus:

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

De plus, j'ai écrasé ImageView pour l'inclure afin de pouvoir le définir en xml . Vous voudrez peut-être ajouter une partie de la logique que le super appel crée ici, mais je l'ai commenté car ce n'est pas utile dans mon cas .

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

J'espère que cela t'aides!

52
Caspar Harmer

J'ai fait par 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);
    }
}

Comment utiliser:

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

Sortie:

 enter image description here

J'espère que cela vous aiderait.

49
Hiren Patel

Image arrondie Utilisation de ImageLoaderici

Créer 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 vous pouvez utiliser la bibliothèque Picasso de 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);

vous pouvez télécharger le fichier RoundedTransformation ici ici

46
shailesh

Comme toutes les réponses semblaient trop compliquées pour moi, rien que pour les angles arrondis, j’ai pensé à une autre solution qu’il vaut la peine de partager, à l’aide de XML, au cas où vous auriez un peu de place autour de l’image:

Créez une forme bordée avec un contenu transparent comme ceci:

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

Ensuite, dans un RelativeLayout, vous pouvez d'abord placer votre image, puis au même endroit au-dessus de la forme avec un autre ImageView. La forme de la couverture doit avoir une taille supérieure à celle de la largeur de la bordure. Veillez à prendre un rayon de coin plus grand, car le rayon extérieur est défini, mais le rayon intérieur recouvre votre image. 

J'espère que ça aide aussi quelqu'un.

Edit selon CQM demande l'exemple de présentation relative:

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

Mon implémentation de ImageView avec un widget coins arrondis, qui (vers le haut || vers le haut) redimensionne l'image aux dimensions requises Il utilise la forme de code 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);

    }

}
13
Damjan

Récemment, il existe un autre moyen - en utilisant l'API générée de Glide . Cela prend un peu de travail initial mais vous donne ensuite toute la puissance de Glide avec la possibilité de faire n'importe quoi parce que vous écrasez le code lui-même, je pense donc que c'est une bonne solution à long terme. De plus, l'utilisation est très simple et soignée.

Premièrement, setup Glide version 4+:

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

Créez ensuite la classe de module d'application de Glid pour déclencher le traitement des annotations:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

Créez ensuite l’extension Glide qui effectue le travail. Vous pouvez le personnaliser pour faire ce que vous voulez:

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

Après avoir ajouté ces fichiers, construisez votre projet.

Puis utilisez-le dans votre code comme ceci:

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

Vous devriez agrandir ImageView et dessiner votre propre rectangle arrondi. 

Si vous souhaitez un cadre autour de l'image, vous pouvez également superposer le cadre arrondi au-dessus de la vue de l'image dans la présentation.

[edit] Superposez le cadre sur l'image d'origine, en utilisant une variable FrameLayout par exemple. Le premier élément de la FrameLayout sera l'image que vous voulez afficher arrondie. Ajoutez ensuite une autre ImageView avec le cadre. La seconde ImageView sera affichée par-dessus la ImageView d'origine et ainsi Android en tirera le contenu au-dessus de la ImageView originale.

7
MrSnowflake

Pour les accessoires de George Walters II ci-dessus, je viens de prendre sa réponse et de l’étendre un peu pour supporter les arrondis individuels différemment. Cela pourrait être optimisé un peu plus loin (certains des objectifs cibles se chevauchent), mais pas beaucoup.

Je sais que ce fil est un peu vieux, mais c’est l’un des meilleurs résultats pour les requêtes sur Google relatives à la manière de contourner les angles d’ImageViews sur 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;
}
6
sorrodos

Il existe une bibliothèque cool qui vous permet de façonner des images.

Voici un exemple:

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

Définition de la forme:

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

Résultat:

 result

6
grrigore

Romain Guy est là.

Version modifiée comme suit.

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

Cette solution XML pure était assez bonne dans mon cas. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-Android-imageview-with-this-hack/

MODIFIER

Voici la réponse en quelques mots:

Dans le dossier/res/drawable, créez un fichier frame.xml. On y définit un rectangle simple avec des angles arrondis et un centre transparent.

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

Dans votre fichier de présentation, vous ajoutez un LinearLayout contenant un ImageView standard, ainsi qu'un FrameLayout imbriqué. Le FrameLayout utilise un rembourrage et un dessin personnalisable pour donner l’illusion de coins arrondis.

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

Ce qui suit crée un objet de mise en page de rectangle arrondi qui dessine un rectangle arrondi autour des objets enfant qui y sont placés. Il montre également comment créer des vues et des mises en forme par programme sans utiliser les fichiers XML de mise en page.

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

La classe d'objet de mise en forme RoundedRectangle est telle que définie ici:

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

pourquoi ne pas couper dans draw ()?

Voici ma solution:

  • étendre RelativeLayout avec le découpage
  • placez ImageView (ou d'autres vues) dans la mise en page:

code:

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

Appliquez une forme à votre imageView comme ci-dessous:

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

cela peut vous être utile, mon ami.

4
jigar

Merci beaucoup d'avoir d'abord répondu. Voici la version modifiée pour convertir une image rectangulaire en une image carrée (et arrondie) et la couleur de remplissage est passée en paramètre.

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
mkm

Une solution xml rapide -

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

Vous pouvez définir la largeur, la hauteur et le rayon souhaités sur CardView et scaleType sur ImageView. 

3
Chirag Mittal

Voici un exemple simple remplaçant imageView, que vous pouvez également utiliser dans le concepteur de modèle pour obtenir un aperçu.

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

}

Ceci est une solution rapide. Le rayon est utilisé à tous les coins et est basé sur un pourcentage de largeur de bitmap.

Je viens de remplacer setImageDrawable et d’utiliser la méthode de support technique v4 pour les images bitmap arrondies.

Usage:

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

Prévisualisation avec imageView et imageView personnalisé:

 enter image description here

3
deadfish

si votre image est sur Internet, le meilleur moyen consiste à utiliser glide et RoundedBitmapDrawableFactory (à partir de l'API 21 - mais disponible dans la bibliothèque de support technique) comme suit:

 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);
    }
});
2
Amir Ziarati

vous pouvez utiliser uniquement ImageView dans votre présentation et utiliser glide, vous pouvez appliquer des angles arrondis à l'aide de cette méthode.

premier dans votre note,

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

pour les images aux coins arrondis,

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éthode d'appel:

loadImageWithCorners("your url","your imageview");
2
Deep Patel

Si vous utilisez Glide Library, cela serait utile:

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

Avec l'aide de glide library et RoundedBitmapDrawableFactory class, c'est facile à réaliser. Vous devrez peut-être créer une image d'espace réservé circulaire.

    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
Chitrang

Répondez à la question qui est redirigée ici: "Comment créer un ImageView circulaire dans Android?"

public static Bitmap getRoundBitmap(Bitmap bitmap) {

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

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

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

    return bitmapRounded;
}
2
Andrey

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)

Pour rendre la circulaire ImageView, nous pouvons modifier cornerRadius par:

rounded.isCircular = true
2
Vahid

Pour ceux qui utilisent Glide et Kotlin, vous pouvez y parvenir en étendant RequestBuilder

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

et utiliser comme;

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

Vous pouvez essayer cette bibliothèque - RoundedImageView

Il est: 

ImageView rapide qui prend en charge les angles arrondis, les ovales et les cercles. Un sur-ensemble complet de CircleImageView.

Je l'ai utilisé dans mon projet et c'est très facile.

1
IgorGanapolsky

Utilisez cette option pour obtenir une image circulaire avec une bordure.

    public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) {
    if (bitmap == null || bitmap.isRecycled()) {
        return null;
    }
    int borderWidth=(int)(bitmap.getWidth()/40);
    final int width = bitmap.getWidth() + borderWidth;
    final int height = bitmap.getHeight() + borderWidth;

    Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
            Bitmap.Config.ARGB_8888);
    BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP,
            TileMode.CLAMP);
    Paint paint = new Paint();
    Paint.setAntiAlias(true);
    Paint.setShader(shader);

    Canvas canvas = new Canvas(canvasBitmap);
    float radius = width > height ? ((float) height) / 2f
            : ((float) width) / 2f;
    canvas.drawCircle(width / 2, height / 2, radius, Paint);
    Paint.setShader(null);
    Paint.setStyle(Paint.Style.STROKE);
    Paint.setColor(bordercolor);
    Paint.setStrokeWidth(borderWidth);
    canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2,
            Paint);
    return canvasBitmap;
}
1
Akshay Paliwal

Beaucoup de réponses!

J'ai suivi cet exemple que quelques personnes ont également suggéré: http://www.techrepublic.com/article/pro-tip-round-corners-on-an-Android-imageview-with-this-hack/

Cependant, il me fallait un cercle coloré derrière une image transparente. Pour ceux qui sont intéressés à faire de même ...

1) Réglez FrameLayout sur la largeur et la hauteur - dans mon cas, la taille de l'image (50dp). 
2) Placez le ImageView portant le src = "@drawable/..." au-dessus du ImageView contenant l’image. Donnez-lui un identifiant, dans mon cas je l'ai appelé iconShape
3) Drawable mask.xml doit avoir une couleur unie de #ffffffff 4. Si vous souhaitez modifier dynamiquement la couleur du cercle dans votre code, faites

ImageView iv2 = (ImageView) v.findViewById(R.id.iconShape);
Drawable shape = getResources().getDrawable(R.drawable.mask);
shape.setColorFilter(Color.BLUE, Mode.MULTIPLY);
iv2.setImageDrawable(shape);
1
rharvey

J'utilise une vue personnalisée que je mets au-dessus des autres et que dessine simplement les 4 petits coins inversés de la même couleur que l'arrière-plan. 

Avantages:

  • N'alloue pas de bitmap.
  • Fonctionne quelle que soit la vue à laquelle vous souhaitez appliquer les coins arrondis.
  • Fonctionne pour tous niveaux d'API;)

Code: 

public class RoundedCornersView extends View {
    private float mRadius;
    private int mColor = Color.WHITE;
    private Paint mPaint;
    private Path mPath;

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

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

        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.RoundedCornersView,
                0, 0);

        try {
            setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
            setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
        } finally {
            a.recycle();
        }
    }

    private void init() {
        setColor(mColor);
        setRadius(mRadius);
    }

    private void setColor(int color) {
        mColor = color;
        mPaint = new Paint();
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        invalidate();
    }

    private void setRadius(float radius) {
        mRadius = radius;
        RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
        mPath = new Path();
        mPath.moveTo(0,0);
        mPath.lineTo(0, mRadius);
        mPath.arcTo(r, 180, 90);
        mPath.lineTo(0,0);
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        /*This just draws 4 little inverted corners */

        int w = getWidth();
        int h = getHeight();
        canvas.drawPath(mPath, mPaint);
        canvas.save();
        canvas.translate(w, 0);
        canvas.rotate(90);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.save();
        canvas.translate(w, h);
        canvas.rotate(180);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.translate(0, h);
        canvas.rotate(270);
        canvas.drawPath(mPath, mPaint);
    }
}
1
mbonnin

vous pouvez utiliser roundedImageView Library très facilement:

compile 'com.makeramen:roundedimageview:2.3.0'

et alors:

<com.makeramen.roundedimageview.RoundedImageView
  xmlns:app="http://schemas.Android.com/apk/res-auto"
  Android:id="@+id/img_episode"
  Android:layout_width="wrap_content"
  Android:layout_height="wrap_content"
  Android:elevation="7dp"
  app:riv_border_color="@color/colorPrimary"
  app:riv_border_width="1dip"
  app:riv_corner_radius="10dip"
  app:riv_mutate_background="true"
  />
0
lococoder

voici ma solution:

<com.myproject.ui.RadiusCornerImageView
        Android:id="@+id/imageViewPhoto"
        Android:layout_width="160dp"
        Android:layout_height="160dp"
        app:corner_radius_dp="5"
        app:corner_radius_position="top"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

Et en code Java:

public class RadiusCornerImageView extends Android.support.v7.widget.AppCompatImageView {
    private int cornerRadiusDP = 0; // dp
    private int corner_radius_position;

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

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

    public RadiusCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RadiusCornerImageView, 0, 0);
        try {
            cornerRadiusDP = typeArray.getInt(R.styleable.RadiusCornerImageView_corner_radius_dp, 0);
            corner_radius_position = typeArray.getInteger(R.styleable.RadiusCornerImageView_corner_radius_position, 0);
        } finally {
            typeArray.recycle();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float radiusPx = AndroidUtil.dpToPx(getContext(), cornerRadiusDP);
        Path clipPath = new Path();
        RectF rect = null;
        if (corner_radius_position == 0) { // all
            // round corners on all 4 angles
            rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        } else if (corner_radius_position == 1) {
            // round corners only on top left and top right
            rect = new RectF(0, 0, this.getWidth(), this.getHeight() + radiusPx);

    } else {
        throw new IllegalArgumentException("Unknown corner_radius_position = " + corner_radius_position);
    }
    clipPath.addRoundRect(rect, radiusPx, radiusPx, Path.Direction.CW);
    canvas.clipPath(clipPath);
    super.onDraw(canvas);
}

}

0
Alex
    /**
 * Background Async task to load user profile picture from url
 */
private class LoadProfileImage extends AsyncTask<String, Void, RoundedBitmapDrawable> {
    ImageView profileImageView;

    public LoadProfileImage(ImageView profileImageView) {
        this.profileImageView = profileImageView;
    }

    protected RoundedBitmapDrawable doInBackground(String... urls) {
        String photoUrl = urls[0];
        RoundedBitmapDrawable profileRoundedDrawable = null;
        try {
            InputStream inputStream = new Java.net.URL(photoUrl).openStream();
            Resources res = getResources();

            profileRoundedDrawable = RoundedBitmapDrawableFactory.create(res, inputStream);
            profileRoundedDrawable.setCircular(true);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return profileRoundedDrawable;
    }

    protected void onPostExecute(RoundedBitmapDrawable result) {
        profileImageView.setImageDrawable(result);
    }
}
0
Norberto Bezi

J'ai utilisé un chemin pour dessiner uniquement des coins sur le canevas d'image (j'avais besoin d'une solution sans allocation de mémoire bitmap).

    @Override
    protected void onDraw(final Canvas canvas) {
        super.onDraw(canvas);

        if (!hasRoundedCorners()) return;

        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(0);

        Path path = new Path();
        path.setFillType(Path.FillType.INVERSE_WINDING);
        path.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRadius, mRadius, Path.Direction.CCW);
        canvas.drawPath(path, mPaint);
    }

remarquez que vous ne devez pas allouer de nouvel objet à la méthode onDraw. Ce code est une preuve de concept et ne doit pas être utilisé de la sorte dans le code produit

voir plus: https://medium.com/@przemek.materna/rounded-image-view-no-bitmap-reallocation-11a8b163484d

0
Cililing
**In Layout**

Make your ImageView like

   <com.example..CircularImageView
            Android:id="@+id/profile_image_round_corner"
            Android:layout_width="80dp"
            Android:layout_height="80dp"
            Android:scaleType="fitCenter"
            Android:padding="2dp"
            Android:background="@null"
            Android:adjustViewBounds="true"
            Android:layout_centerInParent="true"
            Android:src="@drawable/dummy" />



**And Create a Class**

package com.example;

import Java.util.Formatter.BigDecimalLayoutForm;

import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.PorterDuff.Mode;
import Android.graphics.PorterDuffXfermode;
import Android.graphics.Rect;
import Android.graphics.drawable.BitmapDrawable;
import Android.graphics.drawable.Drawable;
import Android.util.AttributeSet;
import Android.widget.ImageView;

public class CircularImageView extends ImageView {

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

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

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

    @Override
    protected void onDraw(Canvas canvas) {

        Drawable drawable = getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

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

        Bitmap roundBitmap = getRoundBitmap(bitmap, w);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

    public static Bitmap getRoundBitmap(Bitmap bmp, int radius) {
        Bitmap sBmp;

        if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
            float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
            float factor = smallest / radius;
            sBmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
        } else {
            sbmp = bmp;
        }

        Bitmap output = Bitmap.createBitmap(radius, radius,
              Bitmap.Config.ARGB_8888);


        Canvas canvas = new Canvas(output);

        final int color = 0xffa19774;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);

        Paint.setAntiAlias(true);
        Paint.setFilterBitmap(true);
        Paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        Paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f,
                radius / 2 + 0.7f, radius / 2 + 0.1f, Paint);
        Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(sBmp, rect, rect, Paint);

        return output;
    }

}
0
Droid_Mechanic

Pour Glide 4.x.x

utiliser ce code simple

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

Ce n'est pas exactement la solution, mais c'est une solution similaire. Cela peut aider les gens qui étaient dans le même bateau que moi.

Mon image, un logo d'application, avait un arrière-plan transparent et j'appliquais un dégradé XML comme arrière-plan. J'ai ajouté les marges de remplissage nécessaires à l'imageView en XML, puis je l'ai ajouté comme fond d'écran:

<?xml version="1.0" encoding="utf-8"?>

<item>

    <shape>

        <gradient
            Android:type="linear"
            Android:startColor="@color/app_color_light_background"
            Android:endColor="@color/app_color_disabled"
            Android:angle="90"
        />

        <!-- Round the top corners. -->
        <corners
            Android:topLeftRadius="@dimen/radius_small"
            Android:topRightRadius="@dimen/radius_small"
        />

    </shape>

</item>

0
Phil Ringsmuth

Si l’un de vous est fait face à ce problème  

enter image description here

Très probablement, vous utilisez Android Studio . En raison de la taille de l'image, et de tous dans Android Studio, vous pouvez rencontrer ce problème Une solution facile à ce problème consiste à diminuer le rayon du cercle dans drawCircle(). Dans mon cas, j'utilise ce correctif

Utiliser canvas.drawCircle(100, 100, 90, Paint); au lieu de canvas.drawCircle(100, 100, 100, Paint); résoudra définitivement votre problème. 

Voici le code finalement édité: -

  public class Profile extends ActionBarActivity {


    TextView username;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.profile);


        username= (TextView) findViewById(R.id.txt);

        String recievedusername=getIntent().getExtras().getString("toname");
        username.setText(recievedusername);


        Bitmap bm = BitmapFactory.decodeResource(getResources(),
                R.mipmap.gomez);

        Bitmap resizedBitmap = Bitmap.createScaledBitmap(bm, 200,200, false);
        Bitmap conv_bm=getCircleBitmap(resizedBitmap,100);
        // set circle bitmap
        ImageView mImage = (ImageView) findViewById(R.id.profile_image);
        mImage.setImageBitmap(conv_bm);
        // TODO Auto-generated method stub
    }
    private Bitmap getCircleBitmap(Bitmap bitmap , int pixels) {
        final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        final 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);
        Paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        Paint.setColor(color);
        canvas.drawCircle(100,100, 90, Paint);
        Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, Paint);
        bitmap.recycle();
        return output;
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_apploud, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_addnew) {
            Intent i;
            i=new Intent(Profile.this,ApplaudSomeone.class);
            startActivity(i);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
0
kumar kundan

Bien que les deux premières réponses fonctionnent, je souhaite en décrire un peu plus… .. Disons que vous avez une activité ou un fragment où se trouve votre ImageView. Vous souhaitez dessiner une image et la redimensionner proportionnellement. Ensuite, vous devriez écrire dans onCreate ou onCreateView comme suit:

LinearLayout rootLayout = (LinearLayout) findViewById(R.id.rootLayout);
ImageView image = (ImageView) findViewById(R.id.image);
// Wait till an activity is visible and image can be measured.
rootLayout.post(new Runnable() {
    @Override
    public void run() {
        // Setting ImageView height with aspect ratio.
        Drawable drawable = ContextCompat.getDrawable(getActivity(), R.drawable.your_image);
        int height = getImageViewHeight(drawable, image);

        // Rounding image corners.
        float radius = getResources().getDimension(R.dimen.your_radius_in_dp);
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        Bitmap result = getRoundedBitmap(bitmap, image.getWidth(), height, radius);
        image.setImageBitmap(result);
    }
});

Où définir une nouvelle hauteur d'image est:

public static int getImageViewHeight(Drawable drawable, ImageView imageView) {
    imageView.setImageDrawable(drawable);
    int width = drawable.getIntrinsicWidth();
    int height = 0;
    if (width > 0) {
        height = (drawable.getIntrinsicHeight() * imageView.getWidth()) / width;
        imageView.getLayoutParams().height = height;
        imageView.requestLayout();
    }
    return height;
}

Ensuite, vous devriez écrire une méthode pour redimensionner une image et arrondir ses angles. Ici, largeur et hauteur sont les nouvelles dimensions d'un bitmap (plus petit ou plus grand). Dans l'exemple suivant, j'arrondis seulement deux coins supérieurs .

private Bitmap getRoundedBitmap(Bitmap bitmap, int width, int height, float radius) {
    // Create scaled bitmap.
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
    BitmapShader shader = new BitmapShader(scaledBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

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

    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    // First make all corners round.
    canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, Paint);
    // Then draw bottom rectangle.
    canvas.drawRect(0, height - radius, radius, height, Paint);
    canvas.drawRect(width - radius, height - radius, width, height, Paint);
    return result;
}
0
CoolMind

Grâce à melanke , vous pouvez utiliser une classe personnalisée et créer une circulaire ImageView personnalisée.

import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.Bitmap.Config;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.PorterDuff.Mode;
import Android.graphics.PorterDuffXfermode;
import Android.graphics.Rect;
import Android.graphics.drawable.BitmapDrawable;
import Android.graphics.drawable.Drawable;
import Android.util.AttributeSet;

public class MLRoundedImageView extends Android.support.v7.widget.AppCompatImageView {

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

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

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

    @Override
    protected void onDraw(Canvas canvas) {

        Drawable drawable = getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

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

        Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

    public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
        Bitmap sbmp;

        if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
            float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
            float factor = smallest / radius;
            sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
        } else {
            sbmp = bmp;
        }

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

        final int color = 0xffa19774;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);

        Paint.setAntiAlias(true);
        Paint.setFilterBitmap(true);
        Paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        Paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f,
                radius / 2 + 0.7f, radius / 2 + 0.1f, Paint);
        Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(sbmp, rect, rect, Paint);

        return output;
    }

}

Et utilisez-le ensuite en XML comme:

<your.package.name.MLRoundedImageView
..
/>

La source

0
Alex Jolig

Essaye ça

Bitmap finalBitmap;
        if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
            finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
                    false);
        else
            finalBitmap = bitmap;
        Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
                finalBitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
                finalBitmap.getHeight());

        Paint.setAntiAlias(true);
        Paint.setFilterBitmap(true);
        Paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        Paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f,
                finalBitmap.getHeight() / 2 + 0.7f,
                finalBitmap.getWidth() / 2 + 0.1f, Paint);
        Paint.setXfermode(new PorterDuffXfermode(
                Android.graphics.PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(finalBitmap, rect, rect, Paint);

        return output;
0
Bhavinkumar Patel

En utilisant le code ci-dessous, vous pouvez modifier le rayon du coin supérieur

    val image = findViewById<ImageView>(R.id.image)
    val curveRadius = 20F

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {

        image.outlineProvider = object : ViewOutlineProvider() {

            @RequiresApi(Build.VERSION_CODES.Lollipop)
            override fun getOutline(view: View?, outline: Outline?) {
                outline?.setRoundRect(0, 0, view!!.width, (view.height+curveRadius).toInt(), curveRadius)
            }
        }

        image.clipToOutline = true

    }
0
Prashant A Gosai