Android Crop Center Of Bitmap

Mam bitmapy, które są kwadratami lub prostokątami. Biorę najkrótszą stronę i robię coś takiego:

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

Następnie skaluję ją do bitmapy 144 x 144 używając tego:

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

Problem polega na tym, że kadruje lewy górny róg oryginalnej bitmapy, ktoś ma kod do kadrowania środka bitmapy?

Author: Ameer Moaaviah, 2011-08-02

9 answers

Tutaj wpisz opis obrazka

Można to osiągnąć za pomocą: 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() 
     );
}
 318
Author: Lumis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-15 10:34:13

Podczas gdy większość powyższych odpowiedzi zapewnia sposób, aby to zrobić, istnieje już wbudowany sposób, aby to osiągnąć i jest to 1 linia kodu (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());
}

Jeśli chcesz, aby obiekt bitmapowy został poddany recyklingowi, możesz przekazać opcje, które sprawiają, że tak jest:

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

From: ThumbnailUtils Documentation

Public static Bitmap extractThumbnail (Bitmap source, int width, int wysokość)

Dodany w API poziom 8 tworzy wyśrodkowaną bitmapę pożądanego rozmiar.

Parametry źródło oryginalna szerokość źródła bitmapy docelowa szerokość wysokość docelowa

Czasami wychodziłem z błędów pamięci, gdy używałem zaakceptowanej odpowiedzi, a korzystanie z miniaturek rozwiązało te problemy. Plus, to jest znacznie czystsze i bardziej wielokrotnego użytku.

 277
Author: DiscDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-14 22:06:14

Czy rozważałeś zrobienie tego z layout.xml? Możesz ustawić dla ImageView ScaleType na android:scaleType="centerCrop" i ustawić wymiary obrazu w ImageView Wewnątrz layout.xml.

 12
Author: Ovidiu Latcu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-02 08:02:05

Możesz użyć następującego kodu, który rozwiąże twój problem.

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

Powyższa metoda wykonuje postScalling obrazu przed kadrowaniem, dzięki czemu można uzyskać najlepszy wynik z kadrowanym obrazem bez błędu OOM.

Więcej szczegółów można znaleźć Ten blog

 9
Author: Hitesh Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-17 11:48:10

Tutaj bardziej kompletny fragment, który wyświetla środek [bitmap] o dowolnych wymiarach i skaluje wynik do żądanego [IMAGE_SIZE] . Tak więc zawsze otrzymasz [croppedBitmap] przeskalowany kwadrat centrum obrazu o stałym rozmiarze. idealny do miniaturek i takich.

To pełniejsza kombinacja innych rozwiązań.
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
Author: willsteel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-21 16:37:57

Prawdopodobnie najprostsze rozwiązanie do tej pory:

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

IMPORT:

import android.media.ThumbnailUtils;
import java.lang.Math;
import android.graphics.Bitmap;
 5
Author: Kirill Kulakov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-25 20:41:14

Aby poprawić @willsteel rozwiązanie:

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
Author: Yman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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
Author: kakopappa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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
Author: Vahe Gharibyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-06 19:46:18