android: créer une image circulaire avec picasso

108

La question avait été posée et une promesse avait été faite pour la version même de Picasso que j'utilise: Comment envoyer un bitmap circulaire à un ImageView à l'aide de Picasso? Je suis nouveau sur Picasso et la seule chose que j'ai utilisée est

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

J'ai déjà trouvé https://gist.github.com/julianshen/5829333 mais je ne sais pas comment le combiner avec la ligne ci-dessus d'une manière non gênante.

Katedral Pillon
la source
Le lien que vous avez donné était suffisant pour répondre à votre propre question. Et vous n'aviez besoin que d'appliquer Picasso. Avec (activité) .load (mayorShipImageLink) .transform (nouveau CircleTransform ()). Into (ImageView);
lagos

Réponses:

286

Faites des recherches un peu avant car il y a des réponses disponibles. Quoi qu'il en soit, suivez ce lien et lisez-le attentivement pour savoir comment l'utiliser.

essaye ça:

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

puis appliquez-le simplement comme:

Picasso.with(activity).load(mayorShipImageLink).transform(new CircleTransform()).into(ImageView);
Anirudh Sharma
la source
@ anirudh-sharma assurez-vous d'ajouter ces importations: import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Paint; import com.squareup.picasso.Transformation;
AG1
1
@all: Si vous entrez dans une exception de pointeur nul sur les images gif, vérifiez ceci
Cerlin
Fonctionne aussi comme un charme à Kotlin. Un changement pour les API existantes, BitmapShader.TileMode.CLAMPn'est plus exsting, j'ai mis à jour la réponse
sud007
NE MARCHE PAS! Signal fatal potentiel 6 (SIGBART) , ce qui signifie que le bitmap.recycle () supprime réellement la réfraction de la mémoire et provoque un messagesignal 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!' -> Abort: `` Erreur, impossible d'accéder à un bitmap invalide / libre ici! parce que ce sont des ordures collectées loin de la mémoire. bitmap.recycleest utilisé pour les appareils Android plus anciens, c'est ce que je comprends.
Haroun Hajem
47

voici quelque chose qui est fourni par la bibliothèque support-v4 ! Regardez dans RoundedBitmapDrawable . Pas besoin de rouler le vôtre:

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

Remarque: Picasso a également un appel .transform (customTransformation) que vous pourriez théoriquement utiliser, cependant, j'ai eu des problèmes avec cela. Cela fonctionne ci-dessus. Bonne chance!

goodKode
la source
Cela fonctionnera parfaitement pour une image carrée. Utilisez Math.min dans le rayon de coin pour n'importe quelle image. imageDrawable.setCornerRadius (Math.min (imageBitmap.getWidth (), imageBitmap.getHeight ()) / 2.0f);
Xplosive
Ne devrions-nous pas créer un thread séparé dans OnSuccess (), car il peut être long de créer un bitmap arrondi à partir du bitmap d'origine?
HasaDev
17

Une autre alternative que j'ai trouvée était cette bibliothèque de gars. Il fonctionne de manière autonome ou en conjonction avec Picasso. J'ai choisi l'itinéraire Picasso, comme ci-dessous:

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

A travaillé pour moi!

Breeno
la source
12

Il existe une bibliothèque de transformation pour Picasso.

Ajoutez simplement une dépendance gradle

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

Fin de l'utiliser

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

Wiki: Transformations de Picasso

Nikolay Krasilnikov
la source
C'est vraiment la réponse parfaite à cette question, comment se fait-il qu'il y ait si peu de votes ..
DDisciple
10

J'ai essayé toutes les solutions ci-dessus mais aucune d'entre elles ne me donne une transformation de cercle sans recadrer l'image .. cette solution ne fonctionnera que pour les images de même largeur et hauteur .. c'est ma solution ci-dessus

première ------

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

alors fais ceci --------

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
la source
8

Utilisez cette bibliothèque pour créer une vue d'image circulaire. Pour créer un ImageView circulaire, ajoutez cette bibliothèque CircularImageView à votre projet et ajoutez CircularImageView dans votre mise en page 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" />`

Ensuite, utilisez Picasso pour charger l'image requise dans cette imageView. Picasso fait toute la mise en cache dont vous n'avez pas besoin de vous en soucier

NIPHIN
la source
2

Inclut le dessin xml de type Layer- list avec le code ci-dessous

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

puis utilisez le xml sur votre ImageView dans le fichier 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
la source
0

Celui-ci fonctionne avec l'instantané Picasso 3 actuel:

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 essentiel: https://gist.github.com/G00fY2/f3fbc468570024930c1fd9eb4cec85a1

G00fY
la source
0

Voici ce qui a fonctionné pour moi avec 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()"
}

}

chabislav
la source