Frage

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

War es hilfreich?

Lösung

Dies ist ziemlich spät als Antwort, aber für alle anderen, die danach suchen, können Sie den folgenden Code erstellen, um die Ecken Ihrer Bilder manuell umzugehen.

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

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

Der endgültige Code sieht so 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!

Andere Tipps

Während die obige Antwort funktioniert, zeigt Romain Guy (ein Kern -Android -Entwickler) eine bessere Methode In seinem Blog, der weniger Speicher verwendet, indem ein Shader verwendet wird, erstellt keine Kopie der Bitmap. Der allgemeine Kern 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);

Die Vorteile dieser Methoden sind, dass es:

  • Erstellt keine separate Kopie der Bitmap, Das verwendet viel Gedächtnis mit großen Bildern [gegen die meisten anderen Antworten hier
  • Unterstützung Antialisasen VS Clippath -Methode
  • Unterstützung Alpha VS XFERMODE+PORTERDUFF -Methode
  • Unterstützung Hardware-Beschleunigung VS Clippath -Methode
  • nur zieht einmal auf die Leinwand VS XFERMODE- und CLIPPATH -Methoden

Ich habe a erstellt RoundEmageView Basierend auf diesem Code, der diese Logik in eine ImageView einbringt und die richtige Fühe fügt ScaleType Unterstützung und eine optionale abgerundete Grenze.

Ein weiterer einfacher Weg ist die Verwendung eines Cardviews mit dem Eckradius und einem ImageView im Inneren:

  <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

In der v21 der Support-Bibliothek gibt es hierfür nun eine Lösung:es heißt RoundedBitmapDrawable.

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

setCornerRadius(float cornerRadius)

Also, beginnend mit Bitmap src und ein Ziel ImageView, es würde ungefähr so ​​aussehen:

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

Der Ausschnitt zu abgerundeten Formen wurde dem hinzugefügt View Klasse in API 21.

Mach das einfach:

  • Erstellen Sie eine abgebildete abgerundete Form, so etwas wie folgt:

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 den Drawable als Hintergrund Ihrer ImageView fest:android:background="@drawable/round_outline"
  • Demzufolge Dokumentation, Sie müssen nur noch hinzufügen android:clipToOutline="true"

Leider gibt es ein Käfer und dieses XML -Attribut wird nicht erkannt. Zum Glück können wir immer noch in Java einschneiden:

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

So wird es aussehen:

enter image description here

Notiz:

Diese Methode funktioniert für irgendein Zeichnende Form (nicht nur abgerundet). Es wird die ImageView auf die Form, die Sie in Ihrem zeichnischen XML definiert haben, übereinstimmen.

Besonderer Hinweis zu ImageViews

setClipToOutline() Funktioniert nur, wenn der Hintergrund der Ansicht auf eine zeichnete Form eingestellt ist. Wenn diese Hintergrundform vorhanden ist, behandelt Sicht die Umrisse der Form als Grenzen für das Ausschneiden und Schattenzwecke.

Dies bedeutet, wenn Sie verwenden möchten setClipToOutline() Um die Ecken auf einem ImageView zu runden android:src Anstatt von android:background (Da der Hintergrund auf Ihre abgerundete Form gesetzt werden muss). Wenn Sie Hintergrund verwenden müssen, um Ihr Bild anstelle von SRC festzulegen, können Sie diese Problemumgehung verwenden:

  • Erstellen Sie ein Layout und setzen Sie seinen Hintergrund auf Ihre Form zu zeichnbar
  • Wickeln Sie das Layout um Ihre ImageView (ohne Polsterung)
  • Das ImageView (einschließlich anderer im Layout) wird nun mit abgerundeter Layoutform angezeigt.

Ich habe von benutzerdefiniertem 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.

Ich stellte fest, dass beide Methoden sehr hilfreich waren, um eine funktionierende Lösung zu finden. Hier ist meine zusammengesetzte Version, die Pixel -unabhängig ist und es Ihnen ermöglicht, einige quadratische Ecken zu haben, wobei der Rest der Ecken denselben Radius hat (was der übliche Anwendungsfall ist). Dank an beide 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 überschreiben, um dies einzulegen, damit ich es in XML definieren kann. Vielleicht möchten Sie einige der Logik hinzufügen, die der Super -Anruf hier tätigt, aber ich habe ihn kommentiert, da er 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!

Abgerundetes Bild mit ImageLoader hier

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

Oder Sie können Benutzer haben Picasso Bibliothek vom Platz.

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 Roundtransformation -Datei hier herunterladenhier

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 Ihre gewünschte Breite, Höhe und Radius auf Cardview und Scaletype auf ImageView festlegen.

Wie alle Antworten für mich zu kompliziert schienen, dachte ich nur für runde Ecken, und kam zu einer anderen Lösung, die ich für einen Teilen wert war, nur mit XML, falls Sie etwas Platz um das Bild haben:

Erstellen Sie eine umrandete Form mit transparenten Inhalten 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> 

Dann können Sie in einem RelATivalout zuerst Ihr Bild und dann an derselben Stelle über der Form mit einem anderen ImageView gelegt. Die Deckform sollte nach der Menge der Grenzbreite größer sein. Achten Sie darauf, einen größeren Eckradius zu nehmen, da der äußere Radius definiert ist, aber der innere Radius ist das, was Ihr Bild abdeckt.

Hoffe es hilft auch jemandem.

Bearbeiten Nach CQM fordern Sie das relative Layout -Beispiel 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>

Meine Implementierung von ImageView mit abgerundetem Ecken -Widget, das (nach unten) Bild zu den erforderlichen Abmessungen. Es wird Codeform verwendet 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);

    }

}

Ab kurzem gibt es einen anderen Weg - Verwenden Glide erzeugte API. Es erfordert einige erste Arbeit, gibt Ihnen aber die Kraft des Gleites mit der Flexibilität, irgendetwas zu tun, weil Sie den tatsächlichen Code geweckt haben. Ich denke, es ist eine gute Lösung langfristig. Außerdem ist die Verwendung sehr einfach und ordentlich.

Erstens ein Setup Gleiten Version 4+:

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

Erstellen Sie dann die App -Modulklasse von Glid, um die Annotationsverarbeitung auszulösen:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

Erstellen Sie dann die Glide -Erweiterung, die tatsächlich die Arbeit erledigt. Sie können es anpassen, um alles zu tun, was Sie wollen:

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

Verwenden Sie es dann in Ihrem Code wie diesem:

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

Da ist ein Coole Bibliothek Dadurch können Sie ImageViews formen.

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

Sie sollten sich ausdehnen ImageView und zeichne dein eigenes abgerundetes Rechteck.

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

bearbeiten] Überlösen Sie den Rahmen, um das Originalbild mit a FrameLayout zum Beispiel. Das erste Element der FrameLayout Wird das Bild sein, das Sie abgerundet haben möchten. Dann fügen Sie einen anderen hinzu ImageView mit dem Rahmen. Der Zweite ImageView wird auf dem Original angezeigt ImageView und so wird Android seinen Inhalt über dem Orignal zeichnen ImageView.

Requisiten an George Walters II. Ich habe nur seine Antwort genommen und sie ein wenig erweitert, um die Rundung einzelner Ecken anders zu unterstützen. Dies könnte etwas weiter optimiert werden (einige der Zielrekorde überlappen), aber nicht viel.

Ich weiß, dass dieser Thread etwas alt ist, aber es ist eines der Top -Ergebnisse für Abfragen bei Google, wie Sie die ImageViews -Ecken auf Android rund machen können.

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

Warum nicht in Draw () einschneiden?

Hier ist meine Lösung:

  • RelATivalout mit Clipping verlängern
  • Geben 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;
    }
}
}

Romain Guy ist dort, wo es ist.

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

Diese reine XML -Lösung war in meinem Fall gut genug. http://www.techrepublic.com/article/pro-pro-fround-corner-on-an--Imageview-with-this-hack/

BEARBEITEN

Hier ist die Antwort auf den Punkt gebracht:

Erstellen Sie im Ordner /res /Drawable eine Frame.xml -Datei. Darin definieren wir ein einfaches Rechteck mit abgerundeten Ecken und a transparent Center.

<?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 Layout -Datei fügen Sie einen Linearlayout hinzu, der eine Standard -ImageView sowie einen verschachtelten Framelayout enthält. Der Framelayout verwendet Polsterung und die individuelle Zeichnung, um die Illusion von abgerundeten Ecken zu ermöglichen.

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

Hier ist ein einfaches Beispiel für Bildansicht. Sie können es 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 Prozentsatz der Bitmap -Breite.

Ich habe gerade außer Kraft gesetzt setImageDrawable und verwendete Unterstützung für die V4 -Methode für abgerundete Bitmap -Zeichnung.

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

Das folgende erzeugt ein abgerundetes Rechteck -Layout -Objekt, das ein abgerundetes Rechteck um alle untergeordneten Kinderobjekte zeichnet. Es zeigt auch, wie Ansichten und Layouts programmgesteuert erstellt werden, ohne die Layout -XML -Dateien zu verwenden.

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

}

Tragen Sie eine Form auf Ihre an imageView wie nachstehend:

<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 Ihren Freund hilfreich sein.

Vielen Dank an die erste Antwort. Hier ist eine modifizierte Version, um ein rechteckiges Bild in ein quadratisches (und abgerundet) umzuwandeln und die Farbe zu füllen 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;
}

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)

Zu machen ImageView Rundschreiben können wir verändern cornerRadius mit:

rounded.isCircular = true

Sie können nur verwenden ImageView in Ihrem Layout und verwenden glide, Sie können mit dieser Methode runde Ecken anwenden.

zuerst in Ihrem Absolventen 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);
                }
            });
}

Anrufmethode:

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

Antwort auf die Frage, die hier umgeleitet wird: "Wie erstelle ich eine kreisförmige ImageView in 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;
}

Mit der Hilfe von gleiten Bibliothek und RoundedBitMapDrawableFactory Klasse Es ist leicht zu erreichen. Möglicherweise müssen Sie zirkuläres 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);
            }
        });

Wenn Ihr Bild im Internet ist, ist es am besten, Glide und zu verwenden RoundedBitmapDrawableFactory (Aus API 21 - aber in der Support Library verfügbar) Like SO:

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

Wenn Sie die Gleitbibliothek 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));
}

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

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

und benutzen als;

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

Ziemlich viele Antworten!

Ich habe diesem Beispiel verfolgt, das einige Leute auch irgendwie vorgeschlagen haben: http://www.techrepublic.com/article/pro-pro-fround-corner-on-an--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 den Framelayout auf Breite und Höhe ein - in meinem Fall die Größe des Bildes (50 dp).
2) Platzieren Sie die ImageView mit Src = "@Drawable/..." über dem ImageView, der das Bild hat. Geben Sie ihm einen Ausweis, in meinem Fall nannte ich es Iconshape
3) Drawable Maske.xml sollte eine feste Farbe von #FFFFFFFFFFFFFFFFFFFFFFERT haben) 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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top