android: picasso ile dairesel görüntü oluşturma


108

Soru sorulmuştu ve kullandığım Picasso'nun tam versiyonu için bir söz verilmişti: Picasso kullanarak bir ImageView'a dairesel bir bitmap'i nasıl gönderebilirim? Picasso'da yeniyim ve kullandığım tek şey

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

Https://gist.github.com/julianshen/5829333'ü zaten buldum ama bunu yukarıdaki satırla garip olmayan bir şekilde nasıl birleştireceğimi bilmiyorum.


Verdiğiniz bağlantı kendi sorunuza cevap vermeniz için yeterliydi. Ve sadece Picasso.with (activity) .load (mayorShipImageLink) .transform (new CircleTransform ()). 'İ (ImageView)' a uygulamanız gerekir;
lagos

Yanıtlar:


286

Cevaplar mevcut olduğundan biraz önce araştırın. Her neyse, Bu Bağlantıyı takip edin ve nasıl kullanılacağını öğrenmek için dikkatlice okuyun.

bunu dene:

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

sonra basitçe şu şekilde uygulayın:

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

@ anirudh-sharma şu içe aktarımları eklediğinizden emin olun: import android.graphics.Bitmap; ithal android.graphics.BitmapShader; ithal android.graphics.Canvas; ithal android.graphics.Paint; ithal com.squareup.picasso.Transformation;
AG1

1
@all: GIF resimlerinde boş işaretçi istisnasına
rastlarsanız

Kotlin'de de bir cazibe gibi çalışıyor. Mevcut API'ler için bir değişiklik, artık mevcut BitmapShader.TileMode.CLAMPdeğil, cevabı güncelledim
sud007

ÇALIŞMIYOR! Potansiyel Ölümcül sinyal 6 (SIGBART) , yani bitmap.recycle () aslında bellekten referansı kaldırıyor ve bir 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!'-> İptal mesajına neden oluyor : 'Hata, burada geçersiz / serbest bırakılmış bir bitmap'e erişilemiyor! çünkü bellekten uzakta toplanan çöptür. bitmap.recycleeski Android cihazlar için kullanılıyor, anladığım şey bu.
Haroun Hajem

47

burada support-v4 kitaplığı tarafından sağlanan bir şey var ! RoundedBitmapDrawable'a bakın . Kendiniz yuvarlamanıza gerek yok:

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

Not: Picasso'nun teorik olarak kullanabileceğiniz bir .transform (customTransformation) çağrısı da vardır , ancak bununla ilgili sorunlarım vardı. Yukarıdaki bu çalışır. İyi şanslar!


Bu, kare görüntü için mükemmel şekilde çalışacaktır. Herhangi bir görüntü için köşe yarıçapında Math.min kullanın. imageDrawable.setCornerRadius (Math.min (imageBitmap.getWidth (), imageBitmap.getHeight ()) / 2.0f);
Xplosive

OnSuccess () 'de ayrı bir iş parçacığı oluşturmamalı mıyız, çünkü orijinal bitmap'ten Yuvarlak bitmap oluşturmak uzun bir görev olabilir mi?
HasaDev

17

Bulduğum başka bir alternatif de bu adamların kütüphanesi. Bağımsız olarak veya Picasso ile birlikte çalışır. Picasso rotasını aşağıdaki gibi seçtim:

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

Benim için çalıştı!


12

Picasso için bir dönüşüm kütüphanesi var.

Sadece kademeli bağımlılık ekleyin

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

Kullanmayı bitir

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

Wiki: Picasso Dönüşümleri


Bu gerçekten bu soru için mükemmel bir cevap, nasıl oluyor da bu kadar az oy alıyor ..
DDisciple

10

Yukarıdaki tüm çözümleri denedim ama hiçbiri bana resmi kırpmadan daire dönüşümü vermiyor ... bu çözüm yalnızca aynı genişlik ve yüksekliğe sahip resimler için işe yarayacak ... yukarıdaki çözümüm bu

ilk ------

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

o zaman bunu yapın --------

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

Dairesel bir görüntü görünümü oluşturmak için bu kitaplığı kullanın. Dairesel bir ImageView oluşturmak için, bu CircularImageView kitaplığını projenize ekleyin ve düzen XML'inize CircularImageView ekleyin

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

Ardından gerekli görüntüyü bu imageView'e yüklemek için picasso'yu kullanın. Picasso endişelenmenize gerek olmayan tüm önbelleğe alma işlemlerini yapar


2

Katman listesi türündeki xml drawable'ı aşağıdaki kodla birlikte ekleyin

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

sonra android.src'de ImageView'unuz için xml kullanın

 <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

Bu, mevcut Picasso 3 anlık görüntüsü ile çalışıyor:

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


0

İşte Picasso v2.71828 ile benim için işe yarayan şey

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

}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.