Skip to content

Instantly share code, notes, and snippets.

@codezjx
Last active July 28, 2023 12:15
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save codezjx/b8a99374385a0210edb9192bced516a3 to your computer and use it in GitHub Desktop.
Save codezjx/b8a99374385a0210edb9192bced516a3 to your computer and use it in GitHub Desktop.
A picasso circle image transformation. Optimized version of: https://gist.github.com/julianshen/5829333. Use shader.setLocalMatrix() method to draw circle bitmap not from source bitmap left-top. So, we no need to create square bitmap!
/**
* Created by codezjx on 2016/5/4.
*/
public class CircleImageTransformation implements Transformation {
/**
* A unique key for the transformation, used for caching purposes.
*/
private static final String KEY = "circleImageTransformation";
@Override
public Bitmap transform(Bitmap source) {
int minEdge = Math.min(source.getWidth(), source.getHeight());
int dx = (source.getWidth() - minEdge) / 2;
int dy = (source.getHeight() - minEdge) / 2;
// Init shader
Shader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Matrix matrix = new Matrix();
matrix.setTranslate(-dx, -dy); // Move the target area to center of the source bitmap
shader.setLocalMatrix(matrix);
// Init paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShader(shader);
// Create and draw circle bitmap
Bitmap output = Bitmap.createBitmap(minEdge, minEdge, source.getConfig());
Canvas canvas = new Canvas(output);
canvas.drawOval(new RectF(0, 0, minEdge, minEdge), paint);
// Recycle the source bitmap, because we already generate a new one
source.recycle();
return output;
}
@Override
public String key() {
return KEY;
}
}
@fbencosme
Copy link

Awesome!

@pladaria
Copy link

Thank you!

@alexmaryin
Copy link

alexmaryin commented Mar 21, 2021

Thank you!

This is a Kotlin version:

import android.graphics.*
import com.squareup.picasso.Transformation

const val KEY = "circleTransformation"

class CircleTransformation : Transformation {

    override fun transform(source: Bitmap?): Bitmap {
        val minEdge = source!!.width.coerceAtMost(source.height)
        val dx = (source.width - minEdge) / 2
        val dy = (source.height - minEdge) / 2
        val shader: Shader = BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
        val matrix = Matrix()
        matrix.setTranslate(-dx.toFloat(), -dy.toFloat())
        shader.setLocalMatrix(matrix)
        val paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint.shader = shader
        val output = Bitmap.createBitmap(minEdge, minEdge, source.config)
        val canvas = Canvas(output)
        canvas.drawOval(RectF(0f, 0f, minEdge.toFloat(), minEdge.toFloat()), paint)
        source.recycle()
        return output
    }

    override fun key(): String {
        return KEY
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment