Comment faire une ImageView avec des coins arrondis?

dans Android, un ImageView est un rectangle par défaut. Comment puis-je en faire un rectangle arrondi (découper les 4 coins de mon Bitmap pour être des rectangles arrondis) dans ImageView?

458
demandé sur Jonik 2010-03-17 07:32:52

30 réponses

c'est assez tard dans la réponse, mais pour n'importe qui d'autre qui est à la recherche pour cela, vous pouvez faire le code suivant pour tourner manuellement les coins de vos images.

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

ce n'est pas mon code, mais je l'ai utilisé et il fonctionne merveilleusement. Je l'ai utilisé comme un assistant dans une classe ImageHelper et l'ai étendu juste un peu pour passer dans la quantité de plumage 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;
    }
}

Espérons que cela aide quelqu'un!

515
répondu George Walters II 2010-09-28 19:33:26

alors que la réponse ci-dessus fonctionne, Romain Guy (un développeur Android de base) montre une meilleure méthode dans son blog qui utilise moins de mémoire en utilisant un shader ne créant pas une copie du bitmap. L'essentiel 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);

l'avantage de cette méthode par rapport aux autres est qu'elle:

  • ne crée pas de copie séparée du bitmap, qui utilise beaucoup de de mémoire avec des images de grande taille [vs la plupart des autres réponses ici]
  • supporte antialisasing [vs méthode clipPath]
  • supporte alpha [vs xfermode+méthode porterduff]
  • supporte hardware acceleration [vs méthode clipPath]
  • seulement , s'appuie une fois sur la toile [vs xfermode et clippath méthodes]

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

185
répondu vinc3m1 2014-12-04 11:28:44

dans la v21 de la bibliothèque de soutien il y a maintenant une solution à cela: elle s'appelle RoundedBitmapDrawable .

c'est fondamentalement comme un tirable normal sauf que vous lui donnez un rayon de coin pour la coupure avec:

setCornerRadius(float cornerRadius)

ainsi, à partir de Bitmap src et une cible ImageView , il ressemblerait à quelque chose comme ceci:

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
103
répondu tyczj 2016-06-08 08:36:04

une autre façon facile est d'utiliser une vue de carte avec le rayon de coin et une vue D'image à 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

94
répondu Taras Vovkovych 2018-04-09 09:37:51
Le

découpé en formes arrondies a été ajouté à la classe View de L'API 21.

faites Simplement ceci:

  • créer une forme arrondie, quelque chose 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 dessiner comme le fond de votre ImageView: android:background="@drawable/round_outline"
  • selon cette documentation , alors tout ce que vous devez faire est d'ajouter android:clipToOutline="true"

malheureusement, il y a un bug et cet attribut XML n'est pas reconnu. Heureusement, nous pouvons encore installer la coupure en Java:

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

voici à quoi il ressemblera:

enter image description here

Note:

cette méthode fonctionne pour n'importe quelle forme étirable (pas seulement arrondie). Il clipera L'ImageView à n'importe quel contour de forme que vous avez défini dans votre xml dessinable.

Note spéciale sur ImageViews

setClipToOutline() ne fonctionne que lorsque le fond de la vue est défini à une forme dessinable. Si cette forme de fond existe, View traite le contour de la forme comme les bordures à des fins de découpage et d'ombrage.

cela signifie que, si vous voulez utiliser setClipToOutline() pour arrondir les coins d'une vue D'Image, votre image doit être réglée en utilisant android:src au lieu de android:background (puisque l'arrière-plan doit être réglé à votre forme arrondie). Si vous devez utiliser background pour définir votre image au lieu de src, vous pouvez utiliser cette solution de contournement:

  • créer une mise en page et mettre son arrière-plan à votre forme dessinable
  • envelopper cette disposition autour de votre ImageView (sans rembourrage)
  • L'ImageView (y compris tout ce qui est dans la mise en page) s'affichera maintenant avec une forme arrondie.
59
répondu hungryghost 2017-07-24 15:30:11

j'ai trouvé que les deux méthodes étaient très utiles pour trouver une solution de travail. Voici ma version composite, c'est-pixel indépendant et vous permet d'avoir certains coins carrés avec le reste des coins ayant le même rayon (ce qui est habituellement le cas d'utilisation). 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;
}

aussi, J'ai outrepassé ImageView pour mettre ceci dans afin que je puisse le définir en xml. Vous pouvez ajouter dans la logique que le super appelle ça fait ici, mais je l'ai commenté car ça n'aide pas 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);
}

Espérons que cette aide!

51
répondu Caspar Harmer 2015-10-15 08:46:09

image arrondie utilisant ImageLoader ici

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 Picasso bibliothèque de la place.

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

44
répondu shailesh 2016-06-30 08:23:09

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

42
répondu Hiren Patel 2018-09-20 10:04:33

comme toutes les réponses semblaient trop compliquées pour moi juste pour les coins ronds j'ai pensé et suis venu à une autre solution qui je pense vaut la peine de partager, juste avec XML au cas où vous avez un peu d'espace autour de l'image:

créer 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> 

vous pouvez ensuite placer votre image D'abord, puis au même endroit au-dessus de la forme avec un autre ImageView. La forme de la couverture doit être de plus grande taille, par la somme de la largeur de la bordure. Faites attention de prendre un plus grand rayon de coin que le rayon extérieur est défini, mais le rayon intérieur est ce qui couvre votre image.

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

modifier conformément à la demande de CQM la disposition relative exemple:

<?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
répondu Christian 2014-02-28 22:46:49

mon implémentation D'ImageView avec un widget arrondi, qui (vers le bas||vers le haut)dimensionne l'image aux dimensions requises. Il utilise le 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
répondu Damjan 2011-10-15 21:12:47

vous devez étendre ImageView et dessiner votre propre rectangle arrondi.

si vous voulez un cadre autour de l'image, vous pouvez également superposer le cadre arrondi sur le dessus de la vue d'image dans la disposition.

[edit]superposer le cadre sur l'image originale, en utilisant un FrameLayout par exemple. Le premier élément du FrameLayout sera l'image que vous voulez diplay arrondie. Puis ajouter un autre ImageView avec le cadre. Deuxième ImageView sera affichée en haut de l'original ImageView et donc Android va dessiner son contenu au-dessus de l'orignal ImageView .

7
répondu MrSnowflake 2010-03-19 10:28:45

accessoires à George Walters II ci-dessus, j'ai juste pris sa réponse et Étendu Un peu pour soutenir arrondir les coins individuels différemment. Cela pourrait être optimisé un peu plus loin (certains de la cible rectangles 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 pour savoir comment arrondir les coins 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
répondu sorrodos 2011-03-04 00:00:36

Romain Guy est là où il est.

version abrégé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
répondu Alex 2013-03-07 05:09:04

ce qui suit crée un objet de disposition rectangulaire arrondi qui dessine un rectangle arrondi autour de tout objet enfant qui y est placé. Il montre également comment créer des vues et des layouts programmatiques sans utiliser les fichiers 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);
 }
}

la classe pour l'objet de mise en page Rondedrectangle 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
répondu Danny Remington - OMS 2010-12-16 17:01:52

pourquoi ne pas faire l'écrêtage dans draw()?

voici ma solution:

  • extend Relativementayout with clipping
  • mettez ImageView (ou d'autres vues) dans le layout:

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
répondu fishautumn 2013-01-22 03:06:56

Merci beaucoup à première réponse. Voici la version modifiée pour convertir une image rectangulaire en une image carrée (et arrondie) et la couleur de remplissage est passé comme 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
répondu mkm 2012-08-03 05:03:20

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>

il peut être utile à votre ami.

4
répondu jigar 2013-07-13 22:17:04

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 un mot:

dans le dossier /res/drawable, créez un cadre.fichier xml. Nous y définissons un rectangle simple avec des coins 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 mise en page, vous ajoutez un affichage en ligne qui contient une vue D'image standard, ainsi qu'un affichage imbriqué. Le FrameLayout utilise le rembourrage et le tirable personnalisé 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>
4
répondu j7nn7k 2014-10-13 16:19:43

depuis peu, il existe un autre moyen - en utilisant API générée par Glide . Il faut un peu de travail initial, mais puis vous donne toute la puissance de planer avec la flexibilité de faire n'importe quoi parce que vous écrivez le code réel donc je pense que c'est une bonne solution pour le long terme. De plus, l'usage est très simple et soigné.

d'Abord, le programme d'installation Glide version 4+:

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

puis créer le module app de Glid classe pour déclencher le traitement d'annotation:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

crée alors l'extension Glide qui fait réellement 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.

alors utilisez - le dans votre code comme ceci:

GlideApp.with(this)
        .load(imageUrl)
        .roundedCorners(getApplicationContext(), 5)
        .into(imageView);
4
répondu Sir Codesalot 2018-08-29 09:27:28

voici un exemple simple qui surpasse imageView, vous pouvez alors également l'utiliser dans layout designer pour prévisualiser.

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

}

c'est pour la solution rapide. Rayon est utilisé sur tous les Coins et est basé sur le pourcentage de la largeur bitmap.

je viens de remplacer setImageDrawable et j'ai utilisé la méthode de support v4 pour le tracable Bitmap arrondi.

Utilisation:

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

Preview avec imageView et imageView personnalisé:

enter image description here

3
répondu deadfish 2016-04-05 10:57:17

réponse à la question qui est redirigée ici: "Comment créer une 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
répondu Andrey 2016-06-21 20:56:21

avec l'aide de glide bibliothèque et RoundedBitmapDrawableFactory classe il est facile à atteindre. Vous devrez peut-être créer une image 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
répondu Chitrang 2016-10-14 06:02:32

si votre image est sur internet la meilleure façon est d'utiliser glide et RoundedBitmapDrawableFactory (de API 21 - mais disponible dans la bibliothèque de soutien) 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
répondu Amir Ziarati 2016-11-06 09:56:04

si vous utilisez la bibliothèque Glide ce 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
répondu Anirudh 2017-12-12 10:52:35

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 faire ImageView circulaire nous pouvons changer cornerRadius avec:

rounded.isCircular = true
2
répondu Vahid 2018-02-04 07:55:52

beaucoup de réponses!

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

cependant, ce dont j'avais besoin était un cercle de couleur, derrière une image transparente. Pour tous ceux qui sont intéressés à faire de même...

1) Régler la largeur et la hauteur du cadre - dans mon cas la taille de l'image (50dp).

2) Placez L'ImageView qui a le src = " @drawable/...", au-dessus de L'ImageView qui a l'image. Donnez-lui une pièce d'identité, dans mon cas je l'ai appelé iconShape

3) Masque Dégainable.le xml devrait avoir une couleur unie de #ffffff 4) Si vous voulez changer 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
répondu rharvey 2014-08-04 10:59:07

vous pouvez essayer cette bibliothèque - RoundedImageView

C'est:

un ImageView rapide qui soutient les coins arrondis, ovales, et les cercles. Un super-ensemble complet de CircleImageView.

je l'ai utilisé dans mon projet, et il est très facile.

1
répondu Igor Ganapolsky 2015-01-07 20:06:50

utilisez ceci pour obtenir une image circulaire avec 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
répondu Akshay Paliwal 2015-09-22 09:40:27

si vous cherchez une fast mais solution sale, vous pouvez utiliser this lib by Vincent Mi.

1
répondu Choletski 2016-10-07 09:06:37

j'utilise une vue personnalisée que je pose sur le dessus des autres et que dessine juste les 4 petits coins inversés dans la même couleur que l'arrière-plan.

avantages:

  • Ne pas affecter une image bitmap.
  • fonctionne quelle que soit la vue que vous voulez appliquer les coins arrondis.
  • Travaille pour tous API niveaux ;)

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
répondu mbonnin 2017-01-28 15:54:52