Android Crop Center of Bitmap

Tengo mapas de bits que son cuadrados o rectangularjs. Tomo el lado más corto y hago algo como esto:

int value = 0; if (bitmap.getHeight() <= bitmap.getWidth()) { value = bitmap.getHeight(); } else { value = bitmap.getWidth(); } Bitmap finalBitmap = null; finalBitmap = Bitmap.createBitmap(bitmap, 0, 0, value, value); 

Luego lo escalo a un bitmap 144 x 144 usando esto:

 Bitmap lastBitmap = null; lastBitmap = Bitmap.createScaledBitmap(finalBitmap, 144, 144, true); 

El problema es que recorta la esquina superior izquierda del bitmap original. ¿Alguien tiene el código para recortar el centro del bitmap?

enter image description here

Esto se puede lograr con: Bitmap.createBitmap (source, x, y, width, height)

 if (srcBmp.getWidth() >= srcBmp.getHeight()){ dstBmp = Bitmap.createBitmap( srcBmp, srcBmp.getWidth()/2 - srcBmp.getHeight()/2, 0, srcBmp.getHeight(), srcBmp.getHeight() ); }else{ dstBmp = Bitmap.createBitmap( srcBmp, 0, srcBmp.getHeight()/2 - srcBmp.getWidth()/2, srcBmp.getWidth(), srcBmp.getWidth() ); } 

Si bien la mayoría de las respuestas anteriores proporcionan una forma de hacerlo, ya existe una forma incorporada de lograr esto y es una línea de código ( ThumbnailUtils.extractThumbnail() )

 int dimension = getSquareCropDimensionForBitmap(bitmap); bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension); ... //I added this method because people keep asking how //to calculate the dimensions of the bitmap...see comments below public int getSquareCropDimensionForBitmap(Bitmap bitmap) { //use the smallest dimension of the image to crop to return Math.min(bitmap.getWidth(), bitmap.getHeight()); } 

Si desea reciclar el objeto de bitmap, puede pasar opciones que lo hagan así:

 bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension, ThumbnailUtils.OPTIONS_RECYCLE_INPUT); 

De: Documentación ThumbnailUtils

público static Bitmap extractThumbnail (fuente de bitmap, ancho int, altura int)

Agregado en el nivel 8 de la API Crea un bitmap centrado del tamaño deseado.

Parámetros fuente origen de bitmap original ancho ancho deseado alto altura de destino

A veces me salían los errores de memoria cuando usaba la respuesta aceptada, y el uso de ThumbnailUtils resolvió esos problemas para mí. Además, esto es mucho más limpio y más reutilizable.

¿Has considerado hacer esto desde el layout.xml ? Puede configurar su ImageView ScaleType en android:scaleType="centerCrop" y establecer las dimensiones de la imagen en ImageView dentro del layout.xml .

Puede utilizar el siguiente código que puede resolver su problema.

 Matrix matrix = new Matrix(); matrix.postScale(0.5f, 0.5f); Bitmap croppedBitmap = Bitmap.createBitmap(bitmapOriginal, 100, 100,100, 100, matrix, true); 

En el método anterior, realice un escaneado de la imagen antes de recortarla, para que pueda obtener el mejor resultado con la imagen recortada sin obtener un error OOM.

Para más detalles, puede referirse a este blog

Aquí un fragmento más completo que saca el centro de un [mapa de bits] de dimensiones arbitrarias y escala el resultado al [IMAGE_SIZE] deseado. Por lo tanto, siempre obtendrá un cuadrado escalado [croppedBitmap] del centro de la imagen con un tamaño fijo. ideal para thumbnailing y tal.

Es una combinación más completa de las otras soluciones.

 final int IMAGE_SIZE = 255; boolean landscape = bitmap.getWidth() > bitmap.getHeight(); float scale_factor; if (landscape) scale_factor = (float)IMAGE_SIZE / bitmap.getHeight(); else scale_factor = (float)IMAGE_SIZE / bitmap.getWidth(); Matrix matrix = new Matrix(); matrix.postScale(scale_factor, scale_factor); Bitmap croppedBitmap; if (landscape){ int start = (tempBitmap.getWidth() - tempBitmap.getHeight()) / 2; croppedBitmap = Bitmap.createBitmap(tempBitmap, start, 0, tempBitmap.getHeight(), tempBitmap.getHeight(), matrix, true); } else { int start = (tempBitmap.getHeight() - tempBitmap.getWidth()) / 2; croppedBitmap = Bitmap.createBitmap(tempBitmap, 0, start, tempBitmap.getWidth(), tempBitmap.getWidth(), matrix, true); } 

Probablemente la solución más fácil hasta el momento:

 public static Bitmap cropCenter(Bitmap bmp) { int dimension = Math.min(bmp.getWidth(), bmp.getHeight()); return ThumbnailUtils.extractThumbnail(bmp, dimension, dimension); } 

importaciones:

 import android.media.ThumbnailUtils; import java.lang.Math; import android.graphics.Bitmap; 

Para corregir la solución @willsteel:

 if (landscape){ int start = (tempBitmap.getWidth() - tempBitmap.getHeight()) / 2; croppedBitmap = Bitmap.createBitmap(tempBitmap, start, 0, tempBitmap.getHeight(), tempBitmap.getHeight(), matrix, true); } else { int start = (tempBitmap.getHeight() - tempBitmap.getWidth()) / 2; croppedBitmap = Bitmap.createBitmap(tempBitmap, 0, start, tempBitmap.getWidth(), tempBitmap.getWidth(), matrix, true); } 
 public static Bitmap resizeAndCropCenter(Bitmap bitmap, int size, boolean recycle) { int w = bitmap.getWidth(); int h = bitmap.getHeight(); if (w == size && h == size) return bitmap; // scale the image so that the shorter side equals to the target; // the longer side will be center-cropped. float scale = (float) size / Math.min(w, h); Bitmap target = Bitmap.createBitmap(size, size, getConfig(bitmap)); int width = Math.round(scale * bitmap.getWidth()); int height = Math.round(scale * bitmap.getHeight()); Canvas canvas = new Canvas(target); canvas.translate((size - width) / 2f, (size - height) / 2f); canvas.scale(scale, scale); Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG); canvas.drawBitmap(bitmap, 0, 0, paint); if (recycle) bitmap.recycle(); return target; } private static Bitmap.Config getConfig(Bitmap bitmap) { Bitmap.Config config = bitmap.getConfig(); if (config == null) { config = Bitmap.Config.ARGB_8888; } return config; } 
 public Bitmap getResizedBitmap(Bitmap bm) { int width = bm.getWidth(); int height = bm.getHeight(); int narrowSize = Math.min(width, height); int differ = (int)Math.abs((bm.getHeight() - bm.getWidth())/2.0f); width = (width == narrowSize) ? 0 : differ; height = (width == 0) ? differ : 0; Bitmap resizedBitmap = Bitmap.createBitmap(bm, width, height, narrowSize, narrowSize); bm.recycle(); return resizedBitmap; }