Bagaimana Mengubah Ukuran Bitmap di Android?

337

Saya memiliki bitmap yang diambil dari Base64 String dari basis data jauh saya, ( encodedImageadalah string yang mewakili gambar dengan Base64):

profileImage = (ImageView)findViewById(R.id.profileImage);

byte[] imageAsBytes=null;
try {
    imageAsBytes = Base64.decode(encodedImage.getBytes());
} catch (IOException e) {e.printStackTrace();}

profileImage.setImageBitmap(
    BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
);

profileImage adalah ImageView saya

Oke, tapi saya harus mengubah ukuran gambar ini sebelum menunjukkannya pada ImageViewtata letak saya. Saya harus mengubah ukurannya menjadi 120x120.

Bisakah seseorang memberi tahu saya kode untuk mengubah ukurannya?

Contoh yang saya temukan tidak bisa diterapkan ke string base64 yang diperoleh bitmap.

NullPointerException
sumber
Kemungkinan duplikat dari Ubah Ukuran Bitmap di Android
Sagar Pilkhwal

Jawaban:

550

Perubahan:

profileImage.setImageBitmap(
    BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)

Untuk:

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));
pengguna432209
sumber
misalkan Anda memiliki gambar resolusi besar katakan 1200x1200 dan ketika Anda menampilkan ini, itu akan penuh dalam tampilan gambar. Jika saya menurunkannya, katakan 75% dan layarnya sehingga menampilkan gambar berskala juga sepenuhnya dalam tampilan gambar, apa yang harus dilakukan untuk layar seperti itu?
jxgn
5
The createScaledBitmap melempar Pengecualian Kehabisan Memori pada Galaxy Tab2 saya yang sangat aneh bagi saya karena ada banyak memori dan tidak ada aplikasi khusus lainnya yang berjalan. Solusi Matrix bekerja.
Ludovic
29
bagaimana jika kita ingin menyimpan aspek rasio ??
Bug Terjadi
3
Bagaimana dengan penskalaan dpi untuk ini? Saya pikir bitmap yang diskalakan harus didasarkan pada tinggi dan lebar layar perangkat?
Doug Ray
2
Menggunakan Bitmap.createScaledBitmap () untuk menurunkan skala gambar lebih dari setengah ukuran aslinya, dapat menghasilkan artefak aliasing. Anda dapat melihat posting yang saya tulis di mana saya mengusulkan beberapa alternatif dan membandingkan kualitas dan kinerja.
Petrake
288
import android.graphics.Matrix
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
    int width = bm.getWidth();
    int height = bm.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    // CREATE A MATRIX FOR THE MANIPULATION
    Matrix matrix = new Matrix();
    // RESIZE THE BIT MAP
    matrix.postScale(scaleWidth, scaleHeight);

    // "RECREATE" THE NEW BITMAP
    Bitmap resizedBitmap = Bitmap.createBitmap(
        bm, 0, 0, width, height, matrix, false);
    bm.recycle();
    return resizedBitmap;
}

EDIT: seperti yang disarankan oleh @aveschini, saya telah menambahkan bm.recycle();kebocoran memori. Harap dicatat bahwa jika Anda menggunakan objek sebelumnya untuk beberapa tujuan lain, maka tangani sesuai.

jeet.chanchawat
sumber
6
Saya mencoba bitmap.createscaledbitmap dan pendekatan matriks ini. Saya menemukan gambar jauh lebih jelas dengan pendekatan matriks. Saya tidak tahu apakah itu biasa atau hanya karena saya menggunakan simulator, bukan telepon. Hanya sebuah petunjuk untuk seseorang yang mengalami masalah yang sama seperti saya.
Anson Yao
2
di sini juga Anda harus menambahkan bm.recycle () untuk kinerja memori yang jauh lebih baik
aveschini
2
Terima kasih atas solusinya, tetapi akan lebih baik jika parameter disusun ulang; public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight). Saya menghabiskan banyak waktu untuk mencari tahu. ; P
Attacktive
1
Perhatikan bahwa impor yang benar untuk Matrix adalah android.graphics.Matrix.
Im
12
Ini sama dengan memanggil Bitmap.createScaledBitmap (). Lihat android.googlesource.com/platform/frameworks/base/+/refs/heads/…
BamsBamx
122

Jika Anda sudah memiliki bitmap, Anda bisa menggunakan kode berikut untuk mengubah ukuran:

Bitmap originalBitmap = <original initialization>;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
    originalBitmap, newWidth, newHeight, false);
ZenBalance
sumber
1
@ pemula jika Anda mengubah ukuran gambar, Anda mungkin melakukan penskalaan berdasarkan dimensi berbeda yang mengubah bitmap menjadi proporsi yang salah atau menghapus beberapa informasi bitmap.
ZenBalance
Saya mencoba mengubah ukuran bitmap berdasarkan proporsi, tetapi kemudian saya mendapatkan kesalahan ini. Disebabkan oleh: java.lang.RuntimeException: Canvas: mencoba menggunakan bitmap daur ulang android.graphics.Bitmap@2291dd13
pemula
@ mulai setiap kali Anda mengubah ukuran bitmap, tergantung pada apa yang Anda lakukan, Anda biasanya perlu membuat salinan yang merupakan ukuran baru, daripada mengubah ukuran bitmap yang ada (karena dalam kasus ini sepertinya referensi ke bitmap adalah sudah didaur ulang dalam memori).
ZenBalance
1
benar .. saya mencobanya dan berfungsi dengan baik sekarang. terima kasih
pemula
39

Skala berdasarkan rasio aspek :

float aspectRatio = yourSelectedImage.getWidth() / 
    (float) yourSelectedImage.getHeight();
int width = 480;
int height = Math.round(width / aspectRatio);

yourSelectedImage = Bitmap.createScaledBitmap(
    yourSelectedImage, width, height, false);

Untuk menggunakan tinggi sebagai alas, ganti lebar menjadi:

int height = 480;
int width = Math.round(height * aspectRatio);
sagit
sumber
24

Skala sebuah bitmap dengan ukuran dan lebar maksimum target, sambil mempertahankan rasio aspek:

int maxHeight = 2000;
int maxWidth = 2000;    
float scale = Math.min(((float)maxHeight / bitmap.getWidth()), ((float)maxWidth / bitmap.getHeight()));

Matrix matrix = new Matrix();
matrix.postScale(scale, scale);

bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Kevin
sumber
7

coba kode ini ini:

BitmapDrawable drawable = (BitmapDrawable) imgview.getDrawable();
Bitmap bmp = drawable.getBitmap();
Bitmap b = Bitmap.createScaledBitmap(bmp, 120, 120, false);

Semoga bermanfaat.

Ravi Makvana
sumber
7

Seseorang bertanya bagaimana menjaga rasio aspek dalam situasi ini:

Hitung faktor yang Anda gunakan untuk penskalaan dan gunakan untuk kedua dimensi. Katakanlah Anda menginginkan gambar setinggi 20% dari layar

int scaleToUse = 20; // this will be our percentage
Bitmap bmp = BitmapFactory.decodeResource(
    context.getResources(), R.drawable.mypng);
int sizeY = screenResolution.y * scaleToUse / 100;
int sizeX = bmp.getWidth() * sizeY / bmp.getHeight();
Bitmap scaled = Bitmap.createScaledBitmap(bmp, sizeX, sizeY, false);

untuk mendapatkan resolusi layar Anda memiliki solusi ini: Dapatkan dimensi layar dalam piksel

Taochok
sumber
3

Coba ini: Fungsi ini mengubah ukuran bitmap secara proporsional. Ketika parameter terakhir diatur ke "X" maka newDimensionXorYdiperlakukan sebagai lebar baru dan ketika diatur ke "Y" ketinggian baru.

public Bitmap getProportionalBitmap(Bitmap bitmap, 
                                    int newDimensionXorY, 
                                    String XorY) {
    if (bitmap == null) {
        return null;
    }

    float xyRatio = 0;
    int newWidth = 0;
    int newHeight = 0;

    if (XorY.toLowerCase().equals("x")) {
        xyRatio = (float) newDimensionXorY / bitmap.getWidth();
        newHeight = (int) (bitmap.getHeight() * xyRatio);
        bitmap = Bitmap.createScaledBitmap(
            bitmap, newDimensionXorY, newHeight, true);
    } else if (XorY.toLowerCase().equals("y")) {
        xyRatio = (float) newDimensionXorY / bitmap.getHeight();
        newWidth = (int) (bitmap.getWidth() * xyRatio);
        bitmap = Bitmap.createScaledBitmap(
            bitmap, newWidth, newDimensionXorY, true);
    }
    return bitmap;
}
pengguna2288580
sumber
3
profileImage.setImageBitmap(
    Bitmap.createScaledBitmap(
        BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length), 
        80, 80, false
    )
);
Rajkamal
sumber
3
  public Bitmap scaleBitmap(Bitmap mBitmap) {
        int ScaleSize = 250;//max Height or width to Scale
        int width = mBitmap.getWidth();
        int height = mBitmap.getHeight();
        float excessSizeRatio = width > height ? width / ScaleSize : height / ScaleSize;
         Bitmap bitmap = Bitmap.createBitmap(
                mBitmap, 0, 0,(int) (width/excessSizeRatio),(int) (height/excessSizeRatio));
        //mBitmap.recycle(); if you are not using mBitmap Obj
        return bitmap;
    }
Sandeep P
sumber
bagi saya itu berhasil setelah sedikit mengetik ulang floS excessSizeRatio = lebar> tinggi? (float) ((float) width / (float) ScaleSize): (float) ((float) height / (float) ScaleSize);
Csabi
3
public static Bitmap resizeBitmapByScale(
            Bitmap bitmap, float scale, boolean recycle) {
        int width = Math.round(bitmap.getWidth() * scale);
        int height = Math.round(bitmap.getHeight() * scale);
        if (width == bitmap.getWidth()
                && height == bitmap.getHeight()) return bitmap;
        Bitmap target = Bitmap.createBitmap(width, height, getConfig(bitmap));
        Canvas canvas = new Canvas(target);
        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;
    }
kakopappa
sumber
2

Ubah Ukuran Bitmap berdasarkan ukuran Layar Apa Pun

public Bitmap bitmapResize(Bitmap imageBitmap) {

    Bitmap bitmap = imageBitmap;
    float heightbmp = bitmap.getHeight();
    float widthbmp = bitmap.getWidth();

    // Get Screen width
    DisplayMetrics displaymetrics = new DisplayMetrics();
    this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    float height = displaymetrics.heightPixels / 3;
    float width = displaymetrics.widthPixels / 3;

    int convertHeight = (int) hight, convertWidth = (int) width;

    // higher
    if (heightbmp > height) {
        convertHeight = (int) height - 20;
        bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
                convertHighet, true);
    }

    // wider
    if (widthbmp > width) {
        convertWidth = (int) width - 20;
        bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
                convertHeight, true);
    }

    return bitmap;
}
Dat Nguyen Thanh
sumber
1

Meskipun jawaban yang diterima benar, itu tidak mengubah ukuran Bitmapdengan mempertahankan Rasio Aspek yang sama . Jika Anda mencari metode untuk mengubah ukuran Bitmapdengan mempertahankan rasio aspek yang sama, Anda dapat menggunakan fungsi utilitas berikut. Detail penggunaan dan penjelasan fungsi ada di tautan ini .

public static Bitmap resizeBitmap(Bitmap source, int maxLength) {
       try {
           if (source.getHeight() >= source.getWidth()) {
               int targetHeight = maxLength;
               if (source.getHeight() <= targetHeight) { // if image already smaller than the required height
                   return source;
               }

               double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
               int targetWidth = (int) (targetHeight * aspectRatio);

               Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
               if (result != source) {
               }
               return result;
           } else {
               int targetWidth = maxLength;

               if (source.getWidth() <= targetWidth) { // if image already smaller than the required height
                   return source;
               }

               double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
               int targetHeight = (int) (targetWidth * aspectRatio);

               Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
               if (result != source) {
               }
               return result;

           }
       }
       catch (Exception e)
       {
           return source;
       }
   }
Asad Ali Choudhry
sumber
0
/**
 * Kotlin method for Bitmap scaling
 * @param bitmap the bitmap to be scaled
 * @param pixel  the target pixel size
 * @param width  the width
 * @param height the height
 * @param max    the max(height, width)
 * @return the scaled bitmap
 */
fun scaleBitmap(bitmap:Bitmap, pixel:Float, width:Int, height:Int, max:Int):Bitmap {
    val scale = px / max
    val h = Math.round(scale * height)
    val w = Math.round(scale * width)
    return Bitmap.createScaledBitmap(bitmap, w, h, true)
  }
Faakhir
sumber
0

Menjaga aspek rasio,

  public Bitmap resizeBitmap(Bitmap source, int width,int height) {
    if(source.getHeight() == height && source.getWidth() == width) return source;
    int maxLength=Math.min(width,height);
    try {
        source=source.copy(source.getConfig(),true);
        if (source.getHeight() <= source.getWidth()) {
            if (source.getHeight() <= maxLength) { // if image already smaller than the required height
                return source;
            }

            double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
            int targetWidth = (int) (maxLength * aspectRatio);

            return Bitmap.createScaledBitmap(source, targetWidth, maxLength, false);
        } else {

            if (source.getWidth() <= maxLength) { // if image already smaller than the required height
                return source;
            }

            double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
            int targetHeight = (int) (maxLength * aspectRatio);

            return Bitmap.createScaledBitmap(source, maxLength, targetHeight, false);

        }
    }
    catch (Exception e)
    {
        return source;
    }
}
Tarasantan
sumber