wake-up-neo.com

Wie erstelle ich eine ImageView mit abgerundeten Ecken?

In Android ist eine ImageView standardmäßig ein Rechteck. Wie kann ich ein abgerundetes Rechteck erstellen (alle 4 Ecken meiner Bitmap ausschneiden, um abgerundete Rechtecke zu bilden) in der ImageView? 

482
michael

Dies ist ziemlich spät, aber für alle anderen, die dies suchen, können Sie den folgenden Code ausführen, um die Ecken Ihrer Bilder manuell abzurunden.

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

Dies ist nicht mein Code, aber ich habe es verwendet und es funktioniert wunderbar. Ich habe es als Helfer in einer ImageHelper-Klasse verwendet und nur ein wenig erweitert, um die Menge an Federn zu überwinden, die ich für ein bestimmtes Bild benötige.

Der endgültige Code sieht folgendermaßen aus:

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

Hoffe das hilft jemandem!

525

Während die obige Antwort funktioniert, zeigt Romain Guy (ein wichtiger Android-Entwickler) eine bessere Methode in seinem Blog, das weniger Speicher benötigt, indem er einen Shader verwendet, der keine Kopie der Bitmap erstellt. Der allgemeine Schwerpunkt der Funktionalität ist hier:

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

Der Vorteil gegenüber anderen Methoden ist, dass es:

  • erstellt keine separate Kopie der Bitmap, die bei großen Bildern viel Speicherplatz benötigt [im Vergleich zu den meisten anderen Antworten hier]
  • unterstützt antialisasing [vs clipPath-Methode]
  • unterstützt alpha [vs xfermode + porterduff-Methode]
  • unterstützt Hardware-Beschleunigung [vs clipPath-Methode]
  • nur zeichnet einmal auf die Leinwand [vs xfermode und clippath method]

Ich habe aus diesem Code ein RoundedImageView erstellt, das diese Logik in eine ImageView umschließt und die richtige ScaleType-Unterstützung und einen optionalen abgerundeten Rand hinzufügt.

196
vinc3m1

Eine andere einfache Möglichkeit ist die Verwendung einer CardView mit dem Eckenradius und einer ImageView darin:

  <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

In der v21 der Support-Bibliothek gibt es jetzt eine Lösung: Es heißt RoundedBitmapDrawable .

Es ist im Grunde genauso wie ein normales Drawable, außer Sie geben ihm einen Eckenradius für den Ausschnitt mit:

setCornerRadius(float cornerRadius)

Ausgehend von Bitmap src und einem Ziel ImageView würde es ungefähr so ​​aussehen:

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

In API 21 wurde der Klasse View das Beschneiden von abgerundeten Formen hinzugefügt.

Mach einfach das:

  • Erstellen Sie eine abgerundete Form, die wie folgt gezeichnet werden kann:

res/drawable/round_outline.xml

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="rectangle">
    <corners Android:radius="10dp" />
    ...
</shape>
  • Legen Sie die Zeichenfläche als Hintergrund für Ihre ImageView fest: Android:background="@drawable/round_outline"
  • Entsprechend dieser Dokumentation müssen Sie nur noch Android:clipToOutline="true" hinzufügen.

Leider gibt es einen Fehler und das XML-Attribut wird nicht erkannt. Zum Glück können wir in Java noch einen Ausschnitt erstellen:

  • In Ihrer Aktivität oder Ihrem Fragment: ImageView.setClipToOutline(true)

So sieht es aus:

enter image description here

Hinweis:

Diese Methode funktioniert für any Drawable Shape (nicht nur gerundet). Dadurch wird die ImageView auf die Formkontur gekürzt, die Sie in Ihrer XML-Zeichendatei definiert haben.

Besonderer Hinweis zu ImageViews

setClipToOutline() funktioniert nur, wenn der Hintergrund der Ansicht auf eine formbare Form festgelegt ist. Wenn diese Hintergrundform vorhanden ist, behandelt View die Kontur der Form als Rahmen für Beschneidungs- und Spiegelungszwecke.

Das heißt, wenn Sie setClipToOutline() verwenden möchten, um die Ecken einer ImageView abzurunden, muss Ihr Bild mit Android:src anstelle von Android:background festgelegt werden (da der Hintergrund auf Ihre abgerundete Form eingestellt werden muss). Wenn Sie ein Bild anstelle von src mit Hintergrund festlegen MÜSSEN, können Sie diese Problemumgehung verwenden:

  • Erstellen Sie ein Layout und setzen Sie den Hintergrund auf Ihre Form
  • Wickeln Sie dieses Layout um Ihre ImageView (ohne Auffüllung)
  • Die ImageView (einschließlich aller anderen Elemente im Layout) wird jetzt mit abgerundeter Layoutform angezeigt.
80
hungryghost

Ich fand, dass beide Methoden sehr hilfreich waren, um eine funktionierende Lösung zu finden. Hier ist meine zusammengesetzte Version, die pixelunabhängig ist und es Ihnen ermöglicht, einige rechteckige Ecken zu haben, wobei die übrigen Ecken den gleichen Radius haben (was der übliche Anwendungsfall ist). Dank der beiden oben genannten Lösungen:

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

Außerdem habe ich ImageView überschrieben, damit ich es in xml definieren kann. Sie möchten vielleicht etwas zur Logik hinzufügen, die der Superaufruf hier macht, aber ich habe es kommentiert, da es in meinem Fall nicht hilfreich ist .

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

Hoffe das hilft!

52
Caspar Harmer

Ich habe es von Custom ImageView gemacht:

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

Wie benutzt man:

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

Ausgabe:

 enter image description here

Hoffe das würde dir helfen.

49
Hiren Patel

Gerundetes Bild Verwenden von ImageLoaderhier

DisplayImageOptions erstellen:

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

Oder Sie können Picasso Library von Square aus verwenden.

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

sie können die RoundedTransformation-Datei hier herunterladen hier

46
shailesh

Da mir alle Antworten nur für runde Ecken zu kompliziert erschienen, dachte ich nach und kam zu einer anderen Lösung, die meiner Meinung nach wert ist, nur mit XML, falls Sie etwas Platz um das Bild herum haben:

Erstellen Sie eine umrandete Form mit transparentem Inhalt wie folgt:

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

In einem relativenLayout können Sie Ihr Bild zuerst platzieren und sich dann mit einer anderen ImageView an derselben Stelle über der Form befinden. Die Coverform sollte um den Umfang der Umrandungsbreite größer sein. Achten Sie darauf, einen größeren Eckenradius zu wählen, da der äußere Radius definiert ist, der innere Radius jedoch das, was Ihr Bild bedeckt. 

Ich hoffe, es hilft auch jemandem.

Edit gemäß CQM fordern Sie das relative Layoutbeispiel an:

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

Meine Implementierung von ImageView mit abgerundeten Ecken-Widget, das das Bild (nach unten || nach oben) auf die erforderlichen Abmessungen vergrößert. Es verwendet die Code-Form 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

Seit kurzem gibt es eine andere Möglichkeit - die generierte API von Glide . Es erfordert einige anfängliche Arbeit, bietet Ihnen dann jedoch die gesamte Leistungsfähigkeit von Glide mit der Flexibilität, alles zu tun, da Sie den eigentlichen Code schreiben, so dass ich denke, dass dies eine gute Lösung für lange Sicht ist. Außerdem ist die Verwendung sehr einfach und ordentlich.

Setup Glide Version 4+:

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

Erstellen Sie anschließend die App-Modulklasse von Glid, um die Anmerkungsverarbeitung auszulösen:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

Dann erstellen Sie die Glide-Erweiterung, die die Arbeit tatsächlich erledigt. Sie können es an Ihre Wünsche anpassen:

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

Erstellen Sie nach dem Hinzufügen dieser Dateien Ihr Projekt.

Dann verwenden Sie es in Ihrem Code wie folgt:

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

Sie sollten ImageView erweitern und Ihr eigenes abgerundetes Rechteck zeichnen. 

Wenn Sie einen Rahmen um das Bild legen möchten, können Sie den abgerundeten Rahmen auch über der Bildansicht im Layout anzeigen.

[Bearbeiten] Einblenden des Rahmens in das Originalbild, z. B. durch Verwendung eines FrameLayout. Das erste Element von FrameLayout ist das Bild, das Sie gerundet zeigen möchten. Fügen Sie dann eine weitere ImageView mit dem Rahmen hinzu. Das zweite ImageView wird über dem ursprünglichen ImageView angezeigt. Daher zeichnet Android seinen Inhalt über das Original ImageView.

7
MrSnowflake

Props zu George Walters II oben, ich habe einfach seine Antwort genommen und etwas erweitert, um das Rundungsverhalten einzelner Ecken anders zu unterstützen. Dies könnte etwas weiter optimiert werden (einige der Zielreize überlappen sich), aber nicht viel.

Ich weiß, dass dieser Thread ein bisschen alt ist, aber es ist eines der Top-Ergebnisse für Abfragen bei Google, wie Ecken von ImageViews unter Android abgerundet werden.

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

Es gibt eine coole Bibliothek , mit der Sie Bildansichten gestalten können.

Hier ist ein Beispiel:

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

Formdefinition:

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

Ergebnis:

 result

6
grrigore

Romain Guy ist da, wo es ist.

Reduzierte Version wie folgt.

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

Diese reine XML-Lösung war in meinem Fall gut genug. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-Android-imageview-mit-this-hack/

EDIT

Hier ist die Antwort in aller Kürze:

Erstellen Sie im Ordner/res/drawable eine frame.xml-Datei. Darin definieren wir ein einfaches Rechteck mit abgerundeten Ecken und einem Zentrum von 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>

In Ihrer Layoutdatei fügen Sie ein LinearLayout hinzu, das eine Standard-ImageView sowie ein verschachteltes FrameLayout enthält. Das FrameLayout verwendet eine Auffüllung und das benutzerdefinierte Zeichenelement, um die Illusion gerundeter Ecken zu erzeugen.

<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

Im Folgenden wird ein abgerundetes Rechteck-Layoutobjekt erstellt, das ein abgerundetes Rechteck um alle darin platzierten untergeordneten Objekte zeichnet. Außerdem wird veranschaulicht, wie Ansichten und Layouts ohne Verwendung der Layout-XML-Dateien programmgesteuert erstellt werden.

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

Die Klasse für das RoundedRectangle-Layoutobjekt ist wie hier definiert:

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

}

warum nicht in draw () schneiden?

Hier ist meine Lösung:

  • relativeLayout mit Clipping erweitern
  • fügen Sie ImageView (oder andere Ansichten) in das Layout ein:

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

Wenden Sie eine Form auf Ihre imageView wie folgt an:

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

es kann für Sie hilfreich sein.

4
jigar

Vielen Dank für die erste Antwort. Hier ist eine modifizierte Version, um ein rechteckiges Bild in ein Quadrat (und abgerundet) umzuwandeln, und die Füllfarbe wird als Parameter übergeben.

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

Eine schnelle XML-Lösung -

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

Sie können die gewünschte Breite, Höhe und den gewünschten Radius in CardView und scaleType in ImageView einstellen. 

3
Chirag Mittal

Hier ist ein einfaches Beispiel, das imageView überschreibt. Sie können es dann auch im Layout-Designer zur Vorschau verwenden.

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

}

Dies ist für eine schnelle Lösung. Der Radius wird an allen Ecken verwendet und basiert auf dem Prozentsatz der Bitmapbreite.

Ich habe gerade setImageDrawable überschrieben und die Methode v4 für abgerundete Bitmaps verwendet.

Verwendungszweck:

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

Vorschau mit imageView und benutzerdefiniertem imageView:

 enter image description here

3
deadfish

wenn sich Ihr Image im Internet befindet, verwenden Sie am besten glide und RoundedBitmapDrawableFactory (von API 21 - aber verfügbar in der Support-Bibliothek):

 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

sie können in Ihrem Layout nur ImageView verwenden. Mit glide können Sie mit dieser Methode abgerundete Ecken anwenden.

zuerst in deinem gradle schreiben,

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

für Bild mit abgerundeten Ecken,

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

Aufrufmethode:

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

Wenn Sie Glide Library verwenden, wäre dies hilfreich:

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

Mit Hilfe von glide library und RoundedBitmapDrawableFactory class ist dies leicht zu erreichen. Möglicherweise müssen Sie ein kreisförmiges Platzhalterbild erstellen.

    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

Beantworten Sie die hier umgeleitete Frage:.

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)

ImageView Circular können wir cornerRadius folgendermaßen ändern:

rounded.isCircular = true
2
Vahid

Für diejenigen, die Glide und Kotlin verwenden, können Sie dies erreichen, indem Sie RequestBuilder erweitern

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

und verwenden als;

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

Sie können diese Bibliothek ausprobieren - RoundedImageView

Es ist: 

Eine schnelle ImageView, die abgerundete Ecken, Ovale und Kreise unterstützt. Eine vollständige Obermenge von CircleImageView.

Ich habe es in meinem Projekt verwendet und es ist sehr einfach.

1
IgorGanapolsky

Verwenden Sie diese Option, um ein kreisförmiges Bild mit

    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

Viele Antworten!

Ich folgte diesem Beispiel, das einige Leute auch vorgeschlagen haben: http://www.techrepublic.com/article/pro-tip-round-corners-on-an-Android-imageview-with-this-hack/

Was ich jedoch brauchte, war ein farbiger Kreis hinter einem transparenten Bild. Für alle, die daran interessiert sind, dasselbe zu tun ...

1) Stellen Sie das FrameLayout auf die Breite und Höhe - in meinem Fall die Größe des Bildes (50dp). 
2) Platzieren Sie die ImageView, die das src = "@drawable/..." hat, über der ImageView, die das Image enthält. Gib mir eine ID, in meinem Fall habe ich es iconShape genannt
3) Drawable mask.xml sollte eine durchgehende Farbe von #ffffffff Haben. 4) Wenn Sie die Kreisfarbe in Ihrem Code dynamisch ändern möchten, tun Sie dies

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

Ich verwende eine benutzerdefinierte Ansicht, die über den anderen angeordnet ist und die 4 kleinen umgekehrten Ecken in derselben Farbe wie der Hintergrund zeichnet. 

Vorteile:

  • Weist keine Bitmap zu.
  • Funktioniert unabhängig von der Ansicht, in der Sie die abgerundeten Ecken anwenden möchten.
  • Funktioniert für all API-Ebenen;)

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

sie können roundImageView Library ganz einfach verwenden:

compile 'com.makeramen:roundedimageview:2.3.0'

und dann:

<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

hier meine Lösung:

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

Und im Java-Code:

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

Ich habe einen Pfad verwendet, um nur Ecken auf der Bildleinwand zu zeichnen (ich brauchte eine Lösung ohne Zuordnung des Bitmap-Speichers).

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

Beachten Sie, dass Sie in der onDraw-Methode kein neues Objekt zuweisen sollten. Dieser Code ist ein Proof of Concept und sollte im Produktcode nicht so verwendet werden

weitere Informationen: 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

Für Glide 4.x.x

benutze diesen einfachen Code

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

Dies ist nicht genau die Antwort, aber es ist eine ähnliche Lösung. Es kann Menschen helfen, die im selben Boot waren wie ich.

Mein Bild, ein Anwendungslogo, hatte einen transparenten Hintergrund und ich wendete einen XML-Farbverlauf als Bildhintergrund an. Ich habe die erforderlichen Füllungen/Ränder zu der imageView in XML hinzugefügt und dann als Hintergrund hinzugefügt:

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

Wenn einer von Ihnen vor diesem Problem steht  

enter image description here

Wahrscheinlich verwenden Sie Android Studio . Aufgrund der Bildgröße und des gesamten Bilds in Android Studio kann dieses Problem auftreten. Eine einfache Lösung für dieses Problem besteht darin, den Kreisradius in drawCircle() zu verringern. In meinem Fall verwende ich diesen Fix

Wenn Sie canvas.drawCircle(100, 100, 90, Paint); anstelle von canvas.drawCircle(100, 100, 100, Paint); verwenden, wird dies definitiv Ihr Problem lösen. 

Hier ist endlich der Code bearbeitet: -

  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

Während die ersten beiden Antworten funktionieren, möchte ich noch ein wenig mehr beschreiben. Sie möchten ein Bild zeichnen und proportional skalieren. Dann sollten Sie in onCreate oder onCreateView folgendes schreiben:

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

Wo eine neue Bildhöhe eingestellt wird:

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

Dann sollten Sie eine Methode schreiben, um ein Bild zu skalieren und seine Ecken abzurunden. Hier sind Breite und Höhe neue Dimensionen einer Bitmap (kleiner oder größer). Im folgenden Beispiel runde ich nur zwei obere Ecken .

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

Dank melanke können Sie eine benutzerdefinierte Klasse verwenden und eine benutzerdefinierte Kreisvariable ImageView erstellen.

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

}

Und dann verwenden Sie es in XML wie:

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

Quelle

0
Alex Jolig

Versuche dies

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

Mit dem folgenden Code können Sie den Radius der oberen Ecke ändern

    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