Imágenes circulares con borde usando Picasso

Habitualmente nos encontramos con la necesidad de utilizar imágenes circulares con borde en el diseño de nuestras aplicaciones. Ante esta situación, el desarrollador se encuentra ante la disyuntiva de:

  • implementar desde cero una solución que sea capaz de crear una imagen circular partiendo de una imagen dada.
  • usar una librería/biblioteca que ofrezca la funcionalidad que necesitamos. Personalmente, uso y recomiendo esta segunda opción (no reinventemos la rueda, si ésta funciona bien). Quiero remarcar que antes de usar cualquier librería de terceros, se deben revisar varios aspectos entre los que destaco como son: la licencia de distribución, calidad del código, errores detectados por otros desarrolladores o el número de estrellas en Github.

Escogiendo esta segunda opción, descubrí varias librerías. Finalmente decidí usar CircleImageView de Henning Dodenhof (hdodenhof) con 3.473 estrellas en Github.

Leyendo los comentarios, me di cuenta que había gente que tenía problemas usándola con librerías de terceros para la gestión de imágenes. Decidí probarla usando Picasso y todo funcionó correctamente. Sin embargo, pese que a que recomiendo el uso de librerías, me gusta usar el mínimo número de ellas por varios de motivos (tamaño del .apk, el conocido límite de los 65K métodos en Android, número de dependencias con terceros, … el tema da para varios posts) Por este motivo y ya que únicamente usaba CircleImageView para disponer de imágenes circulares con borde, característica que no conocía que se podía lograr implementar fácilmente usando la clase com.squareup.picasso.Transformation, me puse manos a la obra.

Para ello he creado la clase BorderedCircleTransform, en la que se pueden definir, a través de su constructor, la anchura y el color del borde (anillo) de la imagen.

BorderedCircleTransform

public class BorderedCircleTransform
        implements Transformation {

    private final int borderWidth;
    private final int borderColor;

    public BorderedCircleTransform(int borderWidth,
                                   int borderColor) {
        this.borderWidth = borderWidth;
        this.borderColor = borderColor;
    }

    @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,
                BitmapShader.TileMode.CLAMP,
                BitmapShader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setAntiAlias(true);

        float r = size / 2f;

        // Prepare the background
        Paint paintBg = new Paint();
        paintBg.setColor(borderColor);
        paintBg.setStyle(Paint.Style.FILL_AND_STROKE);
        paintBg.setAntiAlias(true);

        // Draw the background circle
        canvas.drawCircle(r, r, r, paintBg);

        // Draw the image smaller
        // than the background so a little border will be seen
        canvas.drawCircle(r, r, r - borderWidth, paint);

        squaredBitmap.recycle();
        return bitmap;
    }

    @Override
    public String key() {
        return "bordered_circle";
    }
}

Usando la transformación anterior

picasso.load(IMG_URL)
        .transform(new BorderedCircleTransform(BORDER_WIDTH, Color.BLACK))
        .into(target);

De este modo, tengo la imagen circular con borde que buscaba, consigo eliminar una dependencia en mi aplicación (librería CircleImageView) y continúo usando una librería que, por el momento, es un fijo en mi alineación 😉 (WIN-WIN-WIN).

Espero que os haya gustado el post y sobre todo que os pueda resultar útil en vuestros desarrollos.


Enlaces de interés:

Código del ejemplo | https://github.com/pinicius/BorderedCircleImageExample

CircleImageView de Henning Dodenhof (hdodenhof) | https://github.com/hdodenhof/CircleImageView/issues

Picasso de Square | https://github.com/square/picasso

Imagen de The Black (Asking Alexandria) | http://www.askingalexandria.com/

Album The Black de Asking Alexandria | https://www.youtube.com/watch?v=7appuMrrn7U&list=PLx0u2Yj2r4rBePWpl7lq6b8FiUEuNWKST

  • contacto@pinicius.com
  • (+34) 616810829