안드로이드에서 비트 맵의 ​​크기를 조정하는 방법?


336

원격 데이터베이스에서 Base64 문자열의 비트 맵을 가져 왔습니다 ( encodedImageBase64로 이미지를 나타내는 문자열 임).

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는 내 ImageView입니다

좋아,하지만 ImageView내 레이아웃 에 표시하기 전에이 이미지의 크기를 조정해야 합니다. 120x120으로 크기를 조정해야합니다.

누군가 크기를 조정하는 코드를 말해 줄 수 있습니까?

내가 찾은 예제는 얻은 base64 문자열에 비트 맵을 적용 할 수 없습니다.


답변:


550

변화:

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

에:

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

1200x1200과 같은 큰 해상도 이미지가 있다고 가정하고 이미지를 표시하면 이미지가 가득 찼습니다. 이미지 크기를 75 %로 낮추고 화면이 이미지보기에 크기가 조정 된 이미지를 완전히 표시 할 수 있도록하려면 해당 화면에 대해 어떻게해야합니까?
jxgn

5
createScaledBitmap은 Galaxy Tab2에서 메모리 부족 예외를 발생시킵니다. 메모리가 많고 다른 특정 앱이 실행되고 있지 않기 때문에 매우 이상합니다. 매트릭스 솔루션은 작동합니다.
Ludovic

28
종횡비를 저장하려면 어떻게해야합니까 ??
버그는

3
이것에 대한 dpi 스케일링은 어떻습니까? 스케일 된 비트 맵은 장치 화면 높이와 너비를 기반으로해야한다고 생각합니까?
Doug Ray

2
Bitmap.createScaledBitmap ()을 사용하여 이미지를 원래 크기의 절반 이상으로 축소하면 앨리어싱 아티팩트가 생성 될 수 있습니다. 내가 대안을 제안하고 품질과 성능을 비교 하는 필자가 작성한 게시물을 살펴볼 수 있습니다 .
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;
}

편집 : @aveschini가 제안한대로 bm.recycle();메모리 누수를 추가 했습니다. 다른 목적으로 이전 개체를 사용하는 경우 적절하게 처리하십시오.


6
bitmap.createscaledbitmap 과이 매트릭스 접근법을 모두 시도했습니다. 매트릭스 접근 방식으로 이미지가 훨씬 명확하다는 것을 알았습니다. 그것이 일반적인지 또는 전화 대신 시뮬레이터를 사용하고 있기 때문에 모르겠습니다. 나와 같은 문제를 일으키는 사람을위한 힌트.
Anson Yao

2
더 나은 메모리 성능을 위해 bm.recycle ()을 추가해야합니다
aveschini

2
솔루션에 감사하지만 매개 변수를 다시 정렬하면 더 좋습니다. public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight). 나는 그것을 알아내는 데 시간을 낭비했다. ; P
Attacktive

1
Matrix의 올바른 가져 오기는 android.graphics.Matrix입니다.
Lev

11
이것은 Bitmap.createScaledBitmap () 호출과 동일합니다. 참조 android.googlesource.com/platform/frameworks/base/+/refs/heads/...
BamsBamx

122

비트 맵이 이미있는 경우 다음 코드를 사용하여 크기를 조정할 수 있습니다.

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

1
@beginner 이미지의 크기를 조정하면 비트 맵을 잘못된 비율로 변환하거나 일부 비트 맵 정보를 제거하는 다른 차원을 기준으로 크기를 조정할 수 있습니다.
ZenBalance

비례에 따라 비트 맵의 ​​크기를 조정하려고 시도했지만이 오류가 발생했습니다. 원인 : java.lang.RuntimeException : 캔버스 : 재활용 비트 맵을 사용하려고합니다 android.graphics.Bitmap@2291dd13
초보자

@beginner는 비트 맵의 ​​크기를 조정할 때마다 수행중인 작업에 따라 기존 비트 맵의 ​​크기를 조정하는 대신 새로운 크기의 사본을 만들어야합니다 (이 경우 비트 맵에 대한 참조처럼 보입니다) 이미 메모리에서 재활용되었습니다).
ZenBalance

1
올바른 .. 나는 그것을 시도하고 지금 제대로 작동합니다. 고마워
초보자

39

종횡비 에 따른 스케일 :

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

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

너비의 기본 intead로 높이를 사용하려면 다음으로 변경하십시오.

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

24

종횡비를 유지하면서 대상 최대 크기 및 너비로 비트 맵을 스케일링하십시오.

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

이 코드를 사용해보십시오 :

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

도움이 되길 바랍니다.


7

이 상황에서 가로 세로 비율을 유지하는 방법을 누군가가 물었습니다.

스케일링에 사용중인 요인을 계산하고 두 차원 모두에 사용하십시오. 이미지의 높이가 화면의 20 %가 되길 원한다고하자

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

화면 해상도를 얻는 방법은 다음과 같습니다. 화면 크기를 픽셀 단위 로 가져옵니다.


3

이것을보십시오 :이 함수는 비례 적으로 비트 맵의 ​​크기를 조정합니다. 마지막 매개 변수가 "X" newDimensionXorY로 설정되면 새 너비로 처리되고 "Y"로 설정되면 새 높이로 처리됩니다.

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

나를 위해 그것은 float reSizeping overflowSizeRatio = 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

모든 디스플레이 크기에 따른 비트 맵 크기 조정

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

허용되는 답변은 맞지만 Bitmap동일한 가로 세로 비율 을 유지하여 크기를 조정하지는 않습니다 . Bitmap동일한 종횡비를 유지하여 크기를 조정하는 방법을 찾고 있다면 다음 유틸리티 기능을 사용할 수 있습니다. 기능에 대한 사용법과 설명은 이 링크에 있습니다.

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

종횡비를 유지하면서

  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;
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.