¿Cómo redimensionar los mapas de bits de forma óptima en Android?

Supongamos que tengo un hexágono:

hexágono

Si redimensiono esto para usarlo en mi aplicación que contiene una cuadrícula de hexágonos:

// ... bgPaint = new Paint(); bgPaint.setAntiAlias(true); bgPaint.setDither(true); // ... Bitmap coloredBackground = BitmapFactory.decodeResource(getResources(), R.drawable.bg); // ... canvas.drawBitmap(coloredBackground, null, getAsRect(), bgPaint); 

Entiendo esto:

Hexágonos

getAsRect() devuelve un objeto Rect que uso para dibujar. Lo que quiero lograr es deshacerme de esos píxeles transparentes en los bordes. Creo que estoy haciendo algo mal pero no pude encontrar dónde hasta ahora. ¿Tienes alguna idea de cómo puedo resolver este problema?

Intenté experimentar con dither y antialias pero nada cambió.

3 sugerencias:

1

Intente esto: desactive la escala del sistema cuando decodifique el recurso configurando BitmapFactory.Options.inCalificado en falso:

 Options options = new BitmapFactory.Options(); options.inScaled = false; Bitmap source = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg, options); 

La inScaled debe estar desactivada si necesita una versión no escalada del bitmap.

Luego escala tu bitmap con Bitmap.createScaledBitmap(...) .

2

Otra posible razón es que las líneas negras diagonales de tu mosaico contienen diferentes tonos de gris:

Este es un primer plano de su baldosa:

introduzca la descripción de la imagen aquí

Es suavizado antes de cambiar el tamaño. Cualquier píxel que no sea totalmente negro puede aparecer como un color más claro en las líneas redimensionadas. Puede cambiar sus líneas para que sean completamente negras (0xFF000000) y hacer anti-alias solo después del cambio de tamaño.

3

Otra solución a este problema es diseñar tu mosaico de esta manera:

introduzca la descripción de la imagen aquí

lo que evita el problema de dibujar dos líneas diagonales suavizadas una al lado de la otra.

¿Por qué no usar este en su lugar?

 Bitmap.createScaledBitmap(decodedBitmap, targetWidth, targetHeight, true); 

Podrías probar un algoritmo de cambio de tamaño hqx :

Alternativamente, puedes pintar sobre una superficie más grande y escalar esa superficie por completo.

Estoy redimensionando imágenes como sigue:

  String url = ""; //replace with path to your image int imageDimension = 48; // replace with required image dimension //decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(url), null, o); //Find the correct scale value. It should be the power of 2. final int REQUIRED_SIZE = imageDimension; int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while(true){ if(width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } //decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; Drawable drawable = new BitmapDrawable(context.getResources(), BitmapFactory.decodeStream(new FileInputStream(url), null, o2));