android bitmap crop

Android Crop Center of Bitmap



(9)

Tengo mapas de bits que son cuadrados o rectángulos. 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 mapa de bits 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 mapa de bits original. ¿Alguien tiene el código para recortar el centro del mapa de bits?


¿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 .


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); }


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); }


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;


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


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 mapa de bits, 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 mapa de bits, ancho int, altura int)

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

Parámetros fuente origen de mapa de bits 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.


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() ); }


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; }


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; }