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?

129
demandé sur Ameer Moaaviah 2011-08-02 11:29:36

9 réponses

enter image description here

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() 
     );
}
318
répondu Lumis 2013-07-15 10:34:13

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.

277
répondu DiscDev 2016-03-14 22:06:14

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 .

12
répondu Ovidiu Latcu 2011-08-02 08:02:05

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

9
répondu Hitesh Patel 2012-03-17 11:48:10

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);
}
9
répondu willsteel 2013-01-21 16:37:57

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;
5
répondu Kirill Kulakov 2015-11-25 20:41:14

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);
            }
3
répondu Yman 2012-11-13 11:09:10
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;
}
1
répondu kakopappa 2016-09-01 05:13:18
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;
}
1
répondu Vahe Gharibyan 2016-11-06 19:46:18