android: kreisförmiges bild mit picasso erstellen

108

Die Frage wurde gestellt und es wurde ein Versprechen für die Version von Picasso abgegeben, die ich verwende: Wie sende ich mit Picasso eine kreisförmige Bitmap an eine ImageView? Ich bin neu bei Picasso und habe nur verwendet

Picasso.with(context).load(url).resize(w, h).into(imageview);

Ich habe bereits https://gist.github.com/julianshen/5829333 gefunden , bin mir aber nicht sicher, wie ich es auf unangenehme Weise mit der obigen Zeile kombinieren soll.

Katedral Pillon
quelle
Der von Ihnen angegebene Link reichte aus, um Ihre eigene Frage zu beantworten. Und Sie mussten nur Picasso.with (Aktivität) .load (MayorShipImageLink) .transform (neue CircleTransform ()). In (ImageView) anwenden;
Lagos

Antworten:

286

Recherchieren Sie etwas früher, da Antworten verfügbar sind. Folgen Sie diesem Link und lesen Sie ihn sorgfältig durch, um zu wissen, wie Sie ihn verwenden.

Versuche dies:

import com.squareup.picasso.Transformation;

public class CircleTransform implements Transformation {
    @Override
    public Bitmap transform(Bitmap source) {
        int size = Math.min(source.getWidth(), source.getHeight());

        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
        if (squaredBitmap != source) {
            source.recycle();
        }

        Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());

        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        BitmapShader shader = new BitmapShader(squaredBitmap,
                Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setAntiAlias(true);

        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);

        squaredBitmap.recycle();
        return bitmap;
    }

    @Override
    public String key() {
        return "circle";
    }
}

dann wenden Sie es einfach wie folgt an:

Picasso.with(activity).load(mayorShipImageLink).transform(new CircleTransform()).into(ImageView);
Anirudh Sharma
quelle
@ anirudh-sharma stellen Sie sicher, dass Sie diese Importe hinzufügen: import android.graphics.Bitmap; android.graphics.BitmapShader importieren; android.graphics.Canvas importieren; android.graphics.Paint importieren; import com.squareup.picasso.Transformation;
AG1
1
@all: Wenn Sie auf GIF-Bilder in eine Nullzeiger-Ausnahme geraten, überprüfen Sie dies
Cerlin
Funktioniert auch in Kotlin wie ein Zauber. Eine Änderung für die vorhandenen APIs BitmapShader.TileMode.CLAMPist nicht mehr exsting, ich habe die Antwort aktualisiert
sud007
FUNKTIONIERT NICHT! Potenzielles schwerwiegendes Signal 6 (SIGBART) , was bedeutet, dass die bitmap.recycle () tatsächlich die Aktualisierung aus dem Speicher entfernt und eine signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- 11-12 00:03:47.941 29091 29091 F DEBUG : Abort message: 'Error, cannot access an invalid/free'd bitmap here!'-> Abbruchmeldung verursacht: 'Fehler, kann hier nicht auf eine ungültige / freie Bitmap zugreifen! weil es Müll ist, der aus dem Gedächtnis gesammelt wird. bitmap.recyclewird für ältere Android-Geräte verwendet, verstehe ich.
Haroun Hajem
47

Hier ist etwas, das von der support-v4-Bibliothek bereitgestellt wird ! Schauen Sie in RoundedBitmapDrawable . Sie müssen nicht selbst rollen:

Picasso.with(context).load(url)
                        .resize(w, h)
                        .into(myImageView, new Callback() {
                            @Override
                            public void onSuccess() {
                                Bitmap imageBitmap = ((BitmapDrawable) myImageView.getDrawable()).getBitmap();
                                RoundedBitmapDrawable imageDrawable = RoundedBitmapDrawableFactory.create(getResources(), imageBitmap);
                                imageDrawable.setCircular(true);
                                imageDrawable.setCornerRadius(Math.max(imageBitmap.getWidth(), imageBitmap.getHeight()) / 2.0f);
                                myImageView.setImageDrawable(imageDrawable);
                            }
                            @Override
                            public void onError() {
                                myImageView.setImageResource(R.drawable.default_image);
                            }
                        });

Hinweis: Picasso hat auch einen Aufruf von .transform (customTransformation) , den Sie theoretisch verwenden könnten. Ich hatte jedoch Probleme damit. Das oben funktioniert. Viel Glück!

goodKode
quelle
Dies funktioniert perfekt für quadratische Bilder. Verwenden Sie für jedes Bild Math.min im Eckenradius. imageDrawable.setCornerRadius (Math.min (imageBitmap.getWidth (), imageBitmap.getHeight ()) / 2.0f);
Xplosive
Sollten wir in OnSuccess () keinen separaten Thread erstellen, da das Erstellen einer gerundeten Bitmap aus der Ursprungsbitmap eine lange Aufgabe sein kann?
HasaDev
17

Eine andere Alternative, die ich gefunden habe, war diese Jungsbibliothek. Es funktioniert eigenständig oder in Verbindung mit Picasso. Ich habe die Picasso-Route wie folgt gewählt:

https://github.com/vinc3m1/RoundedImageView

Transformation transformation = new RoundedTransformationBuilder()
          .borderColor(Color.BLACK)
          .borderWidthDp(3)
          .cornerRadiusDp(30)
          .oval(false)
          .build();

Picasso.with(context)
    .load(url)
    .fit()
    .transform(transformation)
    .into(imageView);

Hat für mich gearbeitet!

Breeno
quelle
11

Es gibt eine Transformationsbibliothek für Picasso.

Fügen Sie einfach die Gradle-Abhängigkeit hinzu

implementation 'jp.wasabeef:picasso-transformations:2.2.1'

Verwenden Sie es nicht mehr

Picasso.with(context)
       .load(url)
       .resize(w, h)
       .transform(new CropCircleTransformation())
       .into(imageview);

Wiki: Picasso-Transformationen

Nikolay Krasilnikov
quelle
10

Ich habe alle oben genannten Lösungen ausprobiert, aber keine von ihnen gibt mir eine Kreisumwandlung ohne Zuschneiden des Bildes. Diese Lösung funktioniert nur für Bilder mit der gleichen Breite und Höhe. Dies ist meine Lösung oben

zuerst ------

Picasso.with(getActivity())
            .load(url)
            .error(R.drawable.image2)
            .placeholder(R.drawable.ic_drawer)
            .resize(200, 200)
            .transform(new ImageTrans_CircleTransform())
            .into(imageView1);

dann mach das --------

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader.TileMode;

import com.squareup.picasso.Transformation;
public class ImageTrans_CircleTransform implements Transformation {
 @Override
    public Bitmap transform(Bitmap source) {
 if (source == null || source.isRecycled()) {
                return null;
            }

            final int width = source.getWidth() + borderwidth;
            final int height = source.getHeight() + borderwidth;

            Bitmap canvasBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            BitmapShader shader = new BitmapShader(source, 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);

            //border code
            paint.setShader(null);
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(bordercolor);
            paint.setStrokeWidth(borderwidth);
            canvas.drawCircle(width / 2, height / 2, radius - borderwidth / 2, paint);
            //--------------------------------------

            if (canvasBitmap != source) {
                source.recycle();
            }

            return canvasBitmap;
}
 @Override
    public String key() {
        return "circle";
    }
}
amit
quelle
8

Verwenden Sie diese Bibliothek, um eine kreisförmige Bildansicht zu erstellen. Um eine kreisförmige ImageView zu erstellen, fügen Sie diese CircularImageView-Bibliothek zu Ihrem Projekt hinzu und fügen Sie CircularImageView in Ihr Layout-XML ein

<com.pkmmte.view.CircularImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/image"
        app:border_color="#EEEEEE"
        app:border_width="4dp"
        app:shadow="true" />`

Verwenden Sie dann Picasso, um das gewünschte Bild in diese Bildansicht zu laden. Picasso erledigt das Caching, über das Sie sich keine Sorgen machen müssen

NIPHIN
quelle
2

Fügen Sie die XML-Zeichnung vom Typ Layer-Liste mit dem folgenden Code ein

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/shape_status">
        <shape android:shape="oval">
            <solid android:color="@android:color/black"/>
        </shape>
    </item>
<item android:drawable="@drawable/ic_status_content"/></layer-list>

Verwenden Sie dann die XML-Datei für Ihre ImageView in der Datei android.src

 <ImageView
            android:id="@+id/iconStatus"
            android:layout_width="55dp"
            android:layout_height="55dp"
            android:layout_gravity="right"
            android:src="@drawable/ic_circle_status"
            android:layout_alignParentTop="true"
            android:layout_alignParentEnd="true"/>
Marco Aurelio
quelle
0

Dieser arbeitet mit dem aktuellen Picasso 3-Schnappschuss:

class CircleTransformation : Transformation {

  override fun transform(source: RequestHandler.Result): RequestHandler.Result {
    if (source.bitmap == null) {
      return source
    }

    var bitmap: Bitmap

    // since we cant transform hardware bitmaps create a software copy first
    if (VERSION.SDK_INT >= VERSION_CODES.O && source.bitmap!!.config == Config.HARDWARE) {
      val softwareCopy = source.bitmap!!.copy(Config.ARGB_8888, true)
      if (softwareCopy == null) {
        return source
      } else {
        bitmap = softwareCopy
        source.bitmap!!.recycle()
      }
    } else {
      bitmap = source.bitmap!!
    }

    var size = bitmap.width
    // if bitmap is non-square first create square one
    if (size != bitmap.height) {
      var sizeX = size
      var sizeY = bitmap.height
      size = Math.min(sizeY, sizeX)
      sizeX = (sizeX - size) / 2
      sizeY = (sizeY - size) / 2

      val squareSource = Bitmap.createBitmap(bitmap, sizeX, sizeY, size, size)
      bitmap.recycle()
      bitmap = squareSource
    }

    val circleBitmap = Bitmap.createBitmap(size, size, Config.ARGB_8888)
    val canvas = Canvas(circleBitmap)
    val paint = Paint()
    val shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)

    paint.shader = shader
    paint.isAntiAlias = true
    val centerAndRadius = size / 2f
    canvas.drawCircle(centerAndRadius, centerAndRadius, centerAndRadius, paint)

    bitmap.recycle()
    return RequestHandler.Result(circleBitmap, source.loadedFrom, source.exifRotation)
  }

  override fun key(): String {
    return "circleTransformation()"
  }
}

Picasso3 Kern: https://gist.github.com/G00fY2/f3fbc468570024930c1fd9eb4cec85a1

G00fY
quelle
0

Folgendes hat bei mir mit Picasso v2.71828 funktioniert

class CircleTransform : Transformation {
override fun transform(source: Bitmap?): Bitmap? {
    if (source == null) {
        return source
    }

    var bitmap: Bitmap

    // since we cant transform hardware bitmaps create a software copy first
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && source.config == Bitmap.Config.HARDWARE) {
        val softwareCopy = source.copy(Bitmap.Config.ARGB_8888, true)
        if (softwareCopy == null) {
            return source
        } else {
            bitmap = softwareCopy
            source.recycle()
        }
    } else {
        bitmap = source
    }

    var size = bitmap.width
    // if bitmap is non-square first create square one
    if (size != bitmap.height) {
        var sizeX = size
        var sizeY = bitmap.height
        size = Math.min(sizeY, sizeX)
        sizeX = (sizeX - size) / 2
        sizeY = (sizeY - size) / 2

        val squareSource = Bitmap.createBitmap(bitmap, sizeX, sizeY, size, size)
        bitmap.recycle()
        bitmap = squareSource
    }

    val circleBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(circleBitmap)
    val paint = Paint()
    val shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)

    paint.shader = shader
    paint.isAntiAlias = true
    val centerAndRadius = size / 2f
    canvas.drawCircle(centerAndRadius, centerAndRadius, centerAndRadius, paint)

    bitmap.recycle()
    return circleBitmap
}


override fun key(): String {
    return "circleTransformation()"
}

}}

Chabislav
quelle