android: crea un'immagine circolare con Picasso


108

La domanda era stata posta ed era stata fatta una promessa per la stessa versione di Picasso che sto utilizzando: come faccio a inviare una bitmap circolare a un ImageView utilizzando Picasso? Sono nuovo di Picasso e l'unica cosa che ho usato è

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

Ho già trovato https://gist.github.com/julianshen/5829333 ma non sono sicuro di come combinarlo con la riga sopra in modo non imbarazzante.


Il link che hai fornito è stato sufficiente per rispondere alla tua stessa domanda. E hai solo bisogno di applicare Picasso.with (activity) .load (mayorShipImageLink) .transform (new CircleTransform ()). Into (ImageView);
lagos

Risposte:


286

Fai delle ricerche prima perché ci sono risposte disponibili. Ad ogni modo, segui questo link e leggilo attentamente per sapere come usarlo.

prova questo:

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

quindi applicalo semplicemente come:

Picasso.with(activity).load(mayorShipImageLink).transform(new CircleTransform()).into(ImageView);

@ anirudh-sharma assicurati di aggiungere queste importazioni: import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Paint; import com.squareup.picasso.Transformation;
AG1

1
@all: se si ottiene un'eccezione di puntatore nullo sulle immagini gif, controllare questo
Cerlin

Funziona alla grande anche a Kotlin. Un cambiamento per le API esistenti, BitmapShader.TileMode.CLAMPnon esiste più, ho aggiornato la risposta
sud007

NON FUNZIONA! Potenziale fatale segnale 6 (SIGBART) , il che significa che bitmap.recycle () sta effettivamente rimuovendo il refrence dalla memoria e causando un 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!'-> messaggio di interruzione : 'Errore, non è possibile accedere a una bitmap non valida / libera qui! perché è spazzatura raccolta lontano dalla memoria. bitmap.recycleviene utilizzato per i dispositivi Android meno recenti, è quello che ho capito.
Haroun Hajem

47

ecco qualcosa che viene fornito dalla libreria support-v4 ! Guarda in RoundedBitmapDrawable . Non c'è bisogno di rotolare il tuo:

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

Nota: Picasso ha anche una chiamata .transform (customTransformation) che potresti usare teoricamente, tuttavia, ho avuto problemi con quello. Questo sopra funziona. In bocca al lupo!


Questo funzionerà perfettamente per un'immagine quadrata. Usa Math.min nel raggio dell'angolo per qualsiasi immagine. imageDrawable.setCornerRadius (Math.min (imageBitmap.getWidth (), imageBitmap.getHeight ()) / 2.0f);
Xplosive

Non dovremmo creare un thread separato in OnSuccess (), perché può essere un compito lungo creare una bitmap arrotondata dalla bitmap di origine?
HasaDev

17

Un'altra alternativa che ho trovato è stata questa libreria di ragazzi. Funziona da solo o in combinazione con Picasso. Ho scelto il percorso Picasso, come di seguito:

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

Ha funzionato per me!


12

C'è una libreria di trasformazione per Picasso.

Basta aggiungere gradle dipendenza

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

Finisci di usarlo

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

Wiki: Picasso Transformations


Questa è davvero la risposta perfetta a questa domanda, come mai ha così pochi voti ..
DDisciple

10

Ho provato tutte le soluzioni sopra ma nessuna di esse mi dà la trasformazione del cerchio senza ritagliare l'immagine..questa soluzione funzionerà solo per le immagini con la stessa larghezza e altezza..questa è la mia soluzione sopra

primo ------

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

allora fallo --------

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

8

Usa questa libreria per creare una visualizzazione circolare dell'immagine. Per creare un ImageView circolare, aggiungi questa libreria CircularImageView al tuo progetto e aggiungi CircularImageView nel tuo layout XML

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

Quindi utilizzare picasso per caricare l'immagine richiesta in questo imageView. Picasso fa tutto il caching di cui non devi preoccuparti


2

Includere il disegnabile xml di tipo Layer-list con il codice sottostante

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

quindi usa l'xml per il tuo ImageView in 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"/>


0

Questo funziona con l'attuale snapshot di Picasso 3:

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()"
  }
}

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


0

Ecco cosa ha funzionato per me con Picasso v2.71828

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()"
}

}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.