Android Crop Center de Bitmap
j'ai bitmaps qui sont carrés ou rectangles. Je prends le côté le plus court et je fais quelque chose comme ça:
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);
puis je l'échelle à un 144 x 144 Bitmap en utilisant ceci:
Bitmap lastBitmap = null;
lastBitmap = Bitmap.createScaledBitmap(finalBitmap, 144, 144, true);
problème est-ce qu'il recycle le coin supérieur gauche du bitmap original, Quelqu'un a le code pour recadrer le centre du bitmap?
9 réponses
cela peut être réalisé avec: Bitmap.createBitmap (source, x, y, largeur, hauteur)
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()
);
}
alors que la plupart des réponses ci-dessus fournissent une façon de faire ceci, il y a déjà une façon intégrée d'accomplir ceci et c'est 1 ligne de code ( 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 vous voulez que l'objet bitmap soit recyclé, vous pouvez passer des options qui le rendent ainsi:
bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
From: ThumbnailUtils Documentation
public image statique extractThumbnail (Bitmap source, int largeur, int hauteur)
ajouté au niveau 8 de L'API crée un bitmap centré de la taille désirée.
paramètres source source source bitmap original source width targeted width hauteur visée hauteur
j'ai été sortir des erreurs de mémoire parfois en utilisant la réponse acceptée, et en utilisant ThumbnailUtils résolu ces problèmes pour moi. En plus, c'est plus propre et plus réutilisable.
avez-vous envisagé de faire ça à partir du layout.xml
? Vous pouvez définir pour votre ImageView
le ScaleType à android:scaleType="centerCrop"
et définir les dimensions de l'image dans le ImageView
à l'intérieur du layout.xml
.
vous pouvez utiliser le code suivant qui peut résoudre votre problème.
Matrix matrix = new Matrix();
matrix.postScale(0.5f, 0.5f);
Bitmap croppedBitmap = Bitmap.createBitmap(bitmapOriginal, 100, 100,100, 100, matrix, true);
ci-dessus méthode faire postScalling de l'image avant de recadrer, de sorte que vous pouvez obtenir le meilleur résultat avec l'image recadrée sans obtenir l'erreur OOM.
pour plus de détails, vous pouvez consulter ce blog
voici un extrait plus complet qui recrée le centre d'un [bitmap] de dimensions et d'échelles arbitraires le résultat à votre désiré [IMAGE_SIZE] . Ainsi, vous obtiendrez toujours un [croppedBitmap] carré à l'échelle du centre de l'image avec une taille fixe. idéal pour thumbnailing et ces.
est une combinaison plus complète des autres solutions.
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);
}
probablement la solution la plus facile jusqu'à présent:
public static Bitmap cropCenter(Bitmap bmp) {
int dimension = Math.min(bmp.getWidth(), bmp.getHeight());
return ThumbnailUtils.extractThumbnail(bmp, dimension, dimension);
}
importations:
import android.media.ThumbnailUtils;
import java.lang.Math;
import android.graphics.Bitmap;
pour corriger @willsteel solution:
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;
}