Làm cách nào để thay đổi kích thước Bitmap trong Android?


336

Tôi có một bitmap lấy Chuỗi Base64 từ cơ sở dữ liệu từ xa của tôi, ( encodedImagelà chuỗi đại diện cho hình ảnh với 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 là ImageView của tôi

Ok, nhưng tôi phải thay đổi kích thước hình ảnh này trước khi hiển thị nó trên ImageView bố cục của tôi. Tôi phải thay đổi kích thước của nó thành 120x120.

Ai đó có thể cho tôi biết mã để thay đổi kích thước nó?

Các ví dụ tôi tìm thấy không thể được áp dụng cho chuỗi bit64 cơ sở thu được bitmap.


Câu trả lời:


550

Thay đổi:

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

Đến:

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));

Giả sử bạn có hình ảnh độ phân giải lớn, nói 1200x1200 và khi bạn hiển thị hình ảnh này, nó sẽ có đầy đủ trong hình ảnh. Nếu tôi giảm tỷ lệ xuống 75% và màn hình hiển thị hình ảnh được thu nhỏ cũng hoàn toàn trong chế độ xem hình ảnh, thì nên làm gì cho những màn hình như vậy?
jxgn

5
CreatScaledBitmap loại bỏ ngoại lệ bộ nhớ trên Galaxy Tab2 của tôi, điều này rất kỳ lạ đối với tôi vì có rất nhiều bộ nhớ và không có ứng dụng cụ thể nào đang chạy. Các giải pháp Matrix làm việc mặc dù.
Ludovic

28
Điều gì nếu chúng ta muốn lưu tỷ lệ khung hình ??
Lỗi xảy ra vào

3
Điều gì về quy mô dpi cho điều này? Tôi nghĩ rằng bitmap tỷ lệ nên dựa trên chiều cao và chiều rộng màn hình thiết bị?
Doug Ray

2
Sử dụng Bitmap.createScaledBitmap () để thu nhỏ hình ảnh hơn một nửa kích thước ban đầu, có thể tạo ra các tạo phẩm răng cưa. Bạn có thể xem một bài đăng tôi đã viết nơi tôi đề xuất một số lựa chọn thay thế và so sánh chất lượng và hiệu suất.
Petrakeas

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: theo đề xuất của @aveschini, tôi đã thêm bm.recycle();cho rò rỉ bộ nhớ. Xin lưu ý rằng trong trường hợp nếu bạn đang sử dụng đối tượng trước đó cho một số mục đích khác, thì hãy xử lý tương ứng.


6
Tôi đã thử cả bitmap.createscaledbitmap và cách tiếp cận ma trận này. Tôi thấy hình ảnh rõ ràng hơn nhiều với cách tiếp cận ma trận. Tôi không biết nó phổ biến hay chỉ vì tôi đang sử dụng trình giả lập thay vì điện thoại. Chỉ là một gợi ý cho một người gặp rắc rối tương tự như tôi.
Anson Yao

2
ở đây cũng vậy, bạn phải thêm bm.recycle () để có hiệu suất bộ nhớ tốt hơn nhiều
aveschini

2
Cảm ơn giải pháp, nhưng sẽ tốt hơn nếu các tham số được sắp xếp lại; public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight). Tôi đã dành một thời gian khủng khiếp để tìm ra nó. ; P
Tấn công

1
Lưu ý rằng nhập chính xác cho Matrix là android.graphics.Matrix.
Lev

11
Điều này giống như gọi Bitmap.createScaledBitmap (). Xem android.googlesource.com/pl
platform / frameworks / base / + / refs / head

122

Nếu bạn đã có một bitmap, bạn có thể sử dụng đoạn mã sau để thay đổi kích thước:

Bitmap originalBitmap = <original initialization>;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
    originalBitmap, newWidth, newHeight, false);

1
@beginner nếu bạn thay đổi kích thước hình ảnh, bạn có thể chia tỷ lệ dựa trên các kích thước khác nhau có thể chuyển đổi bitmap thành tỷ lệ không chính xác hoặc xóa một số thông tin bitmap.
ZenBalance

Tôi đã thử thay đổi kích thước bitmap dựa trên tỷ lệ, nhưng sau đó tôi đã gặp lỗi này. Nguyên nhân do: java.lang.R.78Exception: Canvas: cố gắng sử dụng bitmap tái chế android.graphics.Bitmap@2291dd13
người mới bắt đầu

@beginner mỗi khi bạn thay đổi kích thước bitmap, tùy thuộc vào những gì bạn đang làm, bạn thường sẽ cần tạo một bản sao có kích thước mới, thay vì thay đổi kích thước bitmap hiện có (vì trong trường hợp này có vẻ như tham chiếu đến bitmap đã được tái chế trong bộ nhớ).
ZenBalance

1
đúng .. tôi đã thử nó và nó hoạt động đúng bây giờ. cảm ơn
người mới bắt đầu

39

Tỷ lệ dựa trên tỷ lệ khung hình :

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

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

Để sử dụng chiều cao làm cơ sở thay đổi chiều rộng thành:

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

24

Chia tỷ lệ bitmap với kích thước và chiều rộng tối đa của mục tiêu, trong khi duy trì tỷ lệ khung hình:

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

7

thử mã này:

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

Tôi hy vọng nó hữu ích.


7

Có người hỏi làm thế nào để giữ tỷ lệ khung hình trong tình huống này:

Tính hệ số bạn đang sử dụng để chia tỷ lệ và sử dụng nó cho cả hai chiều. Hãy để những người nói rằng bạn muốn một hình ảnh có chiều cao bằng 20% ​​màn hình

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

để có được độ phân giải màn hình, bạn có giải pháp này: Nhận kích thước màn hình bằng pixel


3

Hãy thử điều này: Hàm này thay đổi kích thước bitmap theo tỷ lệ. Khi tham số cuối cùng được đặt thành "X", newDimensionXorYchiều rộng được coi là chiều rộng mới và khi được đặt thành "Y", chiều cao mới.

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

3
profileImage.setImageBitmap(
    Bitmap.createScaledBitmap(
        BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length), 
        80, 80, false
    )
);

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

Đối với tôi, nó hoạt động sau khi gõ lại float floatSizeRatio = width> height? (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;
    }


2

Thay đổi kích thước bitmap dựa trên bất kỳ kích thước hiển thị nào

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

1

Mặc dù câu trả lời được chấp nhận là chính xác, nhưng nó không thay đổi kích thước Bitmapbằng cách giữ nguyên Tỷ lệ khung hình . Nếu bạn đang tìm kiếm một phương pháp để thay đổi kích thước Bitmapbằng cách giữ nguyên tỷ lệ khung hình, bạn có thể sử dụng chức năng tiện ích sau. Các chi tiết sử dụng và giải thích về chức năng có mặt tại liên kết này .

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

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

0

Giữ tỷ lệ khung hình,

  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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.