it-swarm.com.de

Kreisfläche aus Bitmap in Android zuschneiden

Ich habe eine Bitmap und möchte aus dieser Bitmap eine kreisförmige Region beschneiden. Alle Pixel außerhalb des Kreises sollten transparent sein. Wie kann ich das machen?

enter image description here

99
Altaf

Nach langem Brainstorming habe ich die Lösung gefunden

public Bitmap getCroppedBitmap(Bitmap bitmap) {
    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());

    Paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    Paint.setColor(color);
    // canvas.drawRoundRect(rectF, roundPx, roundPx, Paint);
    canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
            bitmap.getWidth() / 2, Paint);
    Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, Paint);
    //Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
    //return _bmp;
    return output;
}
200
Altaf

kreis aus Rechtecken erzeugen

public static Bitmap getCircularBitmap(Bitmap bitmap) {
    Bitmap output;

    if (bitmap.getWidth() > bitmap.getHeight()) {
        output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Config.ARGB_8888);
    } else {
        output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), 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());

    float r = 0;

    if (bitmap.getWidth() > bitmap.getHeight()) {
        r = bitmap.getHeight() / 2;
    } else {
        r = bitmap.getWidth() / 2;
    }

    Paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    Paint.setColor(color);
    canvas.drawCircle(r, r, r, Paint);
    Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, Paint);
    return output;
}
39
diesel

@Gene hat einen Kommentar zu der obigen Antwort abgegeben, in der vorgeschlagen wurde, clipPath als Option zum Zuschneiden eines Bildes als Kreis zu verwenden.

Das Folgende ist eine saubere Implementierung davon:

    public static Bitmap GetBitmapClippedCircle(Bitmap bitmap) {

        final int width = bitmap.getWidth();
        final int height = bitmap.getHeight();
        final Bitmap outputBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);

        final Path path = new Path();
        path.addCircle(
                  (float)(width / 2)
                , (float)(height / 2)
                , (float) Math.min(width, (height / 2))
                , Path.Direction.CCW);

        final Canvas canvas = new Canvas(outputBitmap);
        canvas.clipPath(path);
        canvas.drawBitmap(bitmap, 0, 0, null);
        return outputBitmap;
    }

Dies kann zu einer Dienstprogrammklasse hinzugefügt werden.

30
HGPB

Sie können Ihre Bildansicht mit RoundedBitmapDrawable

hier ist der Code zum Erzielen von roundImageview:

ImageView profilePic=(ImageView)findViewById(R.id.user_image);

//get bitmap of the image
Bitmap imageBitmap=BitmapFactory.decodeResource(getResources(),  R.drawable.large_icon);
RoundedBitmapDrawable roundedBitmapDrawable=RoundedBitmapDrawableFactory.create(getResources(), imageBitmap);

//setting radius
roundedBitmapDrawable.setCornerRadius(50.0f);
roundedBitmapDrawable.setAntiAlias(true);
profilePic.setImageDrawable(roundedBitmapDrawable);
28
sree

Ich denke, dass diese Lösung mit jeder Art von Rechteck besser funktioniert. Ändern Sie die Pixelgröße, wenn Sie ein kleines oder großes Bild wünschen:

public static Bitmap getCircleBitmap(Bitmap bm) {

        int sice = Math.min((bm.getWidth()), (bm.getHeight()));

        Bitmap bitmap = ThumbnailUtils.extractThumbnail(bm, sice, sice);

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(output);

        final int color = 0xffff0000;
        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);
        Paint.setDither(true);
        Paint.setFilterBitmap(true);
        canvas.drawARGB(0, 0, 0, 0);
        Paint.setColor(color);
        canvas.drawOval(rectF, Paint);

        Paint.setColor(Color.BLUE);
        Paint.setStyle(Paint.Style.STROKE);
        Paint.setStrokeWidth((float) 4);
        Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, Paint);

        return output;
    }

Dies kann auch in XML einfach erledigt werden, ohne die eigentliche Bitmap zu beschneiden. Sie müssen lediglich eine kreisförmige Bildmaske erstellen und über dem eigentlichen Bild platzieren. Hier ist der Code, den ich verwendet habe:

circle.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="oval" >
    <gradient Android:startColor="#00FFFFFF" Android:endColor="#00FFFFFF"
        Android:angle="270"/>
     <stroke Android:width="10dp" Android:color="#FFAAAAAA"/>

your_layout.xml (Ignoriere "Android: scaleType =" fitXY "" wenn du es nicht brauchst)

<RelativeLayout

        Android:id="@+id/icon_layout"
        Android:layout_width="@dimen/icon_mask"
        Android:layout_height="@dimen/icon_mask"
        Android:layout_alignParentLeft="true"
        Android:layout_alignParentTop="true" >

        <ImageView
            Android:id="@+id/icon"
            Android:layout_width="@dimen/icon"
            Android:layout_height="@dimen/icon"
            Android:layout_centerInParent="true"
            Android:scaleType="fitXY" >
        </ImageView>

        <ImageView
            Android:id="@+id/icon_mask"
            Android:layout_width="@dimen/icon_mask"
            Android:layout_height="@dimen/icon_mask"
            Android:layout_centerInParent="true"
            Android:background="@drawable/circle"
            Android:scaleType="fitXY" >
        </ImageView>
    </RelativeLayout>

dimen.xml


<dimen name="icon">36dp</dimen>
<dimen name="icon_mask">55dp</dimen>

enter image description here

OutPut Image View:

Hoffe, es könnte für jemanden nützlich sein !!! :)

10
Ash

sie können diesen Code verwenden, es wird funktionieren

public Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
    int targetWidth = 110;
    int targetHeight = 110;
    Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, 
            targetHeight,Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(targetBitmap);
    Path path = new Path();
    path.addCircle(((float) targetWidth - 1) / 2,
            ((float) targetHeight - 1) / 2,
            (Math.min(((float) targetWidth), 
                    ((float) targetHeight)) / 2),
                    Path.Direction.CCW);

    canvas.clipPath(path);
    Bitmap sourceBitmap = scaleBitmapImage;
    canvas.drawBitmap(sourceBitmap, 
            new Rect(0, 0, sourceBitmap.getWidth(),
                    sourceBitmap.getHeight()), 
                    new Rect(0, 0, targetWidth, targetHeight), new Paint(Paint.FILTER_BITMAP_FLAG));
    return targetBitmap;
}
6
anupam sharma

sie können diesen Code verwenden, es wird funktionieren

 private Bitmap getCircleBitmap(Bitmap bitmap) {
        final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(output);

        final int color = Color.RED;
        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.drawOval(rectF, Paint);

        Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, Paint);

        bitmap.recycle();

        return output;
    }
6
user5400869

Nun, richtige Antwort:

private Bitmap getCroppedBitmap(Bitmap bitmap, Integer cx, Integer cy, Integer radius) {
    int diam = radius << 1;
    Bitmap targetBitmap = Bitmap.createBitmap(diam, diam, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(targetBitmap);
    final int color = 0xff424242;
    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    canvas.drawARGB(0, 0, 0, 0);
    Paint.setColor(color);
    canvas.drawCircle(radius, radius, radius, Paint);
    Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, -cx+radius, -cy+radius, Paint);
    return targetBitmap;
}
1
Master

Ich empfehle, bitmap.recycle() hinzuzufügen, wenn Sie es nicht mehr benötigen, da dies den OutOfMemory-Fehler verhindert.

1
badoualy

Basierend auf der Antwort von [Jachumbelechao Unto Mantekilla] wirkt dieser Code wie ein Zauber für Leute, die nach einer Kotlin-Lösung suchen:

fun cropCircleFromBitmap(originalBitmap: Bitmap): Bitmap {
    val size = Math.min(originalBitmap.width, originalBitmap.height)
    val bitmap = ThumbnailUtils.extractThumbnail(originalBitmap, size, size)
    var output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(output)
    val Paint = Paint()
    val rect = Rect(0, 0, bitmap.width, bitmap.height)
    val rectF = RectF(rect)
    Paint.isAntiAlias = true
    Paint.isDither = true
    Paint.isFilterBitmap = true
    canvas.drawARGB(0, 0, 0, 0)
    Paint.color = 0xffff0000.toInt()
    canvas.drawOval(rectF, Paint)
    Paint.color = Color.BLUE
    Paint.style = Paint.Style.STROKE
    Paint.strokeWidth = 4f
    Paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
    canvas.drawBitmap(bitmap, rect, rect, Paint)
    return output
}
1
Rodrigo Salinas

Hier ist Kotlin-Variante mit Erweiterungsmethode

/**
 * Creates new circular bitmap based on original one.
 */
fun Bitmap.getCircularBitmap(config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap {
    // circle configuration
    val circlePaint = Paint().apply { isAntiAlias = true }
    val circleRadius = Math.max(width, height) / 2f

    // output bitmap
    val outputBitmapPaint = Paint(circlePaint).apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) }
    val outputBounds = Rect(0, 0, width, height)
    val output = Bitmap.createBitmap(width, height, config)

    return Canvas(output).run {
        drawCircle(circleRadius, circleRadius, circleRadius, circlePaint)
        drawBitmap([email protected], outputBounds, outputBounds, outputBitmapPaint)
        output
    }
}
1
Yuriy Seredyuk

Kotlin-Funktion

 fun getRoundedCornerBitmap(bitmap: Bitmap, pixels: Int): Bitmap {
            val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(output)

            val color = -0xbdbdbe
            val Paint = Paint()
            val rect = Rect(0, 0, bitmap.width, bitmap.height)
            val rectF = RectF(rect)
            val roundPx = pixels.toFloat()

            Paint.isAntiAlias = true
            canvas.drawARGB(0, 0, 0, 0)
            Paint.color = color
            canvas.drawRoundRect(rectF, roundPx, roundPx, Paint)

            Paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
            canvas.drawBitmap(bitmap, rect, rect, Paint)

            return output
        }

nennen Sie es mit diesem Code

 holder.itemFriendImage.setImageBitmap(ImageConverter.getRoundedCornerBitmap(bitmap,600))
1
Samet öztoprak

Für Leute, die den Mittelpunkt des Rechtecks ​​(mich) haben möchten, fügen Sie dies vor dem Schneiden hinzu:

    public static Bitmap cropBitmapToBlock(Bitmap bitmap) {
    if (bitmap.getWidth() >= bitmap.getHeight()){
        return Bitmap.createBitmap(
                bitmap,
                bitmap.getWidth()/2 - bitmap.getHeight()/2,
                0,
                bitmap.getHeight(),
                bitmap.getHeight()
        );
    }else{
        return Bitmap.createBitmap(
                bitmap,
                0,
                bitmap.getHeight()/2 - bitmap.getWidth()/2,
                bitmap.getWidth(),
                bitmap.getWidth()
        );
    }
} 

Android Crop Center von Bitmap

1
jobbert

Ich glaube, die einfachste Lösung ist, einen BitmapShader Ihrer Bitmap zu erstellen, ihn an Ihr Paint-Objekt zu übergeben und dann einfach etwas wie canvas.drawCircle (cx, cy, radius, Paint) aufzurufen.

zum Beispiel

Paint p = new Paint();
p.setShader(new BitmapShader(myBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getHeight() / 2, p);

So hat https://github.com/hdodenhof/CircleImageView es auch getan, Den Quellcode können Sie hier lesen: https://github.com/hdodenhof/CircleImageView /blob/master/circleimageview/src/main/Java/de/hdodenhof/circleimageview/CircleImageView.Java

0
Martin Nowosad
**Jst Add this to your image Id and get the circuler image.**

 imgUserProfile.setImageBitmap(getCircularCenterCropBitmap(bitmap, (int) (150 * denisty)));

Method:-

public void Bitmap getCircularCenterCropBitmap(Bitmap originalBmp, int diameter) {
        Bitmap resizedBmp = BitmapUtils.getScaledCroppedBitmap(originalBmp, diameter, diameter);
        return BitmapUtils.getRoundedCircularBitmap(resizedBmp, diameter / 2);
    }
0
Alok Singh