ic_dialog_email - selector android studio
Cómo usar RoundedBitmapDrawable (6)
¿Alguien ha logrado usar RoundedBitmapDrawable
? Corríjame si me equivoco, pero a mi entender, hace una imagen circular de una imagen rectangular regular.
Lo que he intentado hasta ahora es esto
RoundedBitmapDrawable.createRoundedBitmapDrawable(getResources(), BitmapFactory.decodeResource(getResources(), iconResource))
Lo que intenté lograr: transformar cualquier imagen en una imagen circular y mostrarla utilizando un ImageView.
En caso de que mezclé las cosas y todo lo que dije no tiene sentido. ¿Es posible (o más simple) hacerlo con alguno de los nuevos marcos? (Android L o nueva biblioteca de soporte)
Creé una clase de utilidad para crear RoundedBitmapDrawables https://gist.github.com/lawloretienne/a91fb0ce40f083073d4b8939281b3ecb
Funciona para círculos y cuadrados redondeados.
public class RoundedBitmapDrawableUtility {
public static RoundedBitmapDrawable getRoundedSquareBitmapDrawable(Context context, Bitmap originalBitmap, int cornerRadius){
return getRoundedSquareBitmapDrawable(context, originalBitmap, cornerRadius, -1, -1);
}
public static RoundedBitmapDrawable getRoundedSquareBitmapDrawable(Context context, Bitmap originalBitmap, int cornerRadius, int borderWidth, int borderColor){
int originalBitmapWidth = originalBitmap.getWidth();
int originalBitmapHeight = originalBitmap.getHeight();
if(borderWidth != -1 && borderColor != -1){
Canvas canvas = new Canvas(originalBitmap);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Paint borderPaint = new Paint();
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth);
borderPaint.setAntiAlias(true);
borderPaint.setColor(borderColor);
int roundedRectDelta = (borderWidth/3);
RectF rectF = new RectF(0 + roundedRectDelta, 0 + roundedRectDelta, originalBitmapWidth - roundedRectDelta, originalBitmapHeight - roundedRectDelta);
canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, borderPaint);
}
RoundedBitmapDrawable roundedImageBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), originalBitmap);
roundedImageBitmapDrawable.setCornerRadius(cornerRadius);
roundedImageBitmapDrawable.setAntiAlias(true);
return roundedImageBitmapDrawable;
}
public static RoundedBitmapDrawable getCircleBitmapDrawable(Context context, Bitmap originalBitmap){
return getCircleBitmapDrawable(context, originalBitmap, -1, -1);
}
public static RoundedBitmapDrawable getCircleBitmapDrawable(Context context, Bitmap originalBitmap, int borderWidth, int borderColor){
if(borderWidth != -1 && borderColor != -1) {
Canvas canvas = new Canvas(originalBitmap);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Paint borderPaint = new Paint();
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth);
borderPaint.setAntiAlias(true);
borderPaint.setColor(borderColor);
int circleDelta = (borderWidth / 2) - DisplayUtility.dp2px(context, 1);
int radius = (canvas.getWidth() / 2) - circleDelta;
canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, radius, borderPaint);
}
RoundedBitmapDrawable roundedImageBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), originalBitmap);
roundedImageBitmapDrawable.setCircular(true);
roundedImageBitmapDrawable.setAntiAlias(true);
return roundedImageBitmapDrawable;
}
}
La forma actual en que RoundedBitmapDrawable funciona en imágenes no cuadradas no es tan buena. Hace que el contenido se extienda.
Sugiero usar una alternativa para esto, como he escrito aquí: ¿Cómo tener una vista de imágenes circular y recortada en el centro sin crear un nuevo mapa de bits?
Me gustaría sugerir otra opción:
puede utilizar este método para escalarlo según sus necesidades y evitar esta excepción:
public static Bitmap scaleBitmapAndKeepRation(Bitmap TargetBmp, int reqHeightInPixels, int reqWidthInPixels) {
if (TargetBmp != null) {
if (TargetBmp.getWidth() >= TargetBmp.getHeight()) {
TargetBmp = Bitmap.createBitmap(
TargetBmp,
TargetBmp.getWidth() / 2 - TargetBmp.getHeight() / 2,
0,
TargetBmp.getHeight(),
TargetBmp.getHeight()
);
} else {
TargetBmp = Bitmap.createBitmap(
TargetBmp,
0,
TargetBmp.getHeight() / 2 - TargetBmp.getWidth() / 2,
TargetBmp.getWidth(),
TargetBmp.getWidth()
);
}
if (TargetBmp != null) {
try {
Matrix m = new Matrix();
m.setRectToRect(new RectF(0, 0, TargetBmp.getWidth(), TargetBmp.getHeight()), new RectF(0, 0, reqWidthInPixels, reqHeightInPixels), Matrix.ScaleToFit.FILL);
Bitmap scaledBitmap = Bitmap.createBitmap(TargetBmp, 0, 0, TargetBmp.getWidth(), TargetBmp.getHeight(), m, true);
return scaledBitmap;
} catch (Exception e) {
Log.e("Utils", e.toString());
return null;
}
}
return null;
} else
return null;
}
Necesitas establecer el radio de la esquina.
Resources res = getResources();
Bitmap src = BitmapFactory.decodeResource(res, iconResource);
RoundedBitmapDrawable dr =
RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(Math.max(src.getWidth(), src.getHeight()) / 2.0f);
imageView.setImageDrawable(dr);
Puede ser una respuesta tardía, pero espero que sea útil para otros
Si su imagen tiene el mismo ancho y alto, simplemente puede establecer setCircular en true para obtener el mapa de bits redondeado de la siguiente manera
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getResources(),your_bitmap);
drawable.setCircular(true);
También estoy encontrando una vista de imagen redondeada para mayor eficiencia. Busqué en una biblioteca de terceros. Descubrí que todos ellos están creando un nuevo mapa de bits, lo que es una tarea tediosa en la lista que consume más memoria.
biblioteca arbitrada
- http://ruibm.com/2009/06/16/rounded-corner-bitmaps-on-android/
- https://github.com/vinc3m1/RoundedImageView
- https://github.com/lopspower/CircularImageView
de esta biblioteca he usado
porque un rápido ImageView (y Drawable) que soporta esquinas redondeadas (y óvalos o círculos) basado en el ejemplo original de Romain Guy
- No crea una copia del mapa de bits original.
- no utiliza un clipPath que no sea acelerado por hardware y no sea suavizado.
- no utiliza setXfermode para recortar el mapa de bits y dibujar dos veces en el lienzo.