android: buat gambar melingkar dengan picasso


108

Pertanyaan telah diajukan dan sudah ada janji yang dibuat untuk versi Picasso yang saya gunakan: Bagaimana cara mengirim bitmap melingkar ke ImageView menggunakan Picasso? Saya baru mengenal Picasso dan satu-satunya hal yang pernah saya gunakan adalah

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

Saya sudah menemukan https://gist.github.com/julianshen/5829333 tetapi saya tidak yakin bagaimana menggabungkannya dengan baris di atas dengan cara yang tidak canggung.


Tautan yang Anda berikan sudah cukup untuk menjawab pertanyaan Anda sendiri. Dan Anda hanya perlu menerapkan Picasso.with (activity) .load (mayorShipImageLink) .transform (new CircleTransform ()). Into (ImageView);
lagos

Jawaban:


286

Riset sedikit sebelumnya karena ada jawaban yang tersedia. Bagaimanapun, ikuti Tautan Ini dan baca dengan cermat untuk mengetahui cara menggunakannya.

coba ini:

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

lalu cukup terapkan seperti:

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

@ anirudh-sharma pastikan untuk menambahkan impor ini: import android.graphics.Bitmap; impor android.graphics.BitmapShader; impor android.graphics.Canvas; impor android.graphics.Paint; impor com.squareup.picasso.Transformation;
AG1

1
@ Semua: Jika Anda mendapatkan pengecualian pointer nol pada gambar gif, periksa ini
Cerlin

Bekerja seperti pesona di Kotlin juga. Satu perubahan untuk API yang ada, BitmapShader.TileMode.CLAMPtidak ada lagi, saya telah memperbarui jawabannya
sud007

TIDAK BEKERJA! Potential Fatal signal 6 (SIGBART) , yang berarti bahwa bitmap.recycle () sebenarnya menghapus refence dari memori dan menyebabkan 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!'-> Abort pesan: 'Error, tidak dapat mengakses bitmap yang tidak valid / gratis di sini! karena sampah dikumpulkan jauh dari memori. bitmap.recycledigunakan untuk perangkat Android yang lebih lama, itulah yang saya mengerti.
Haroun Hajem

47

ini adalah sesuatu yang disediakan oleh pustaka support-v4 ! Lihat RoundedBitmapDrawable . Tidak perlu menggulung sendiri:

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

Catatan: Picasso juga memiliki panggilan .transform (customTransformation) yang secara teoritis dapat Anda gunakan, namun saya mengalami masalah dengan itu. Ini di atas bekerja. Semoga berhasil!


Ini akan bekerja dengan sempurna untuk gambar persegi. Gunakan Math.min dalam radius sudut untuk gambar apapun. imageDrawable.setCornerRadius (Math.min (imageBitmap.getWidth (), imageBitmap.getHeight ()) / 2.0f);
Xplosive

Bukankah kita harus membuat utas terpisah di OnSuccess (), karena akan memakan waktu lama untuk membuat bitmap Rounded dari bitmap asal?
HasaDev

17

Alternatif lain yang saya temukan adalah perpustakaan orang ini. Ia bekerja secara mandiri, atau dalam hubungannya dengan Picasso. Saya memilih rute Picasso, seperti di bawah ini:

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

Bekerja untuk saya!


12

Ada perpustakaan transformasi untuk Picasso.

Tambahkan saja ketergantungan gradle

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

Akhiri gunakan

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

Wiki: Transformasi Picasso


Ini benar-benar jawaban yang sempurna untuk pertanyaan ini, kenapa
suaranya

10

Saya telah mencoba semua solusi di atas tetapi tidak ada yang memberi saya transformasi lingkaran tanpa memotong gambar .. solusi itu hanya akan berfungsi untuk gambar dengan lebar dan tinggi yang sama..ini adalah solusi saya di atas

pertama ------

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

lalu lakukan ini --------

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

Gunakan perpustakaan ini untuk membuat imageview melingkar. Untuk membuat ImageView melingkar, tambahkan pustaka CircularImageView ini ke proyek Anda dan tambahkan CircularImageView di XML tata letak Anda

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

Kemudian gunakan picasso untuk memuat gambar yang diperlukan ke imageView ini. Picasso melakukan semua caching Anda tidak perlu khawatir tentang itu


2

Sertakan drawable xml dari tipe Layer- list dengan kode di bawah ini

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

lalu gunakan xml ke ImageView Anda di 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

Yang ini bekerja dengan snapshot Picasso 3 saat ini:

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

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


0

Inilah yang berhasil untuk saya dengan 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()"
}

}

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.