Android'de Bir Bitmap Nasıl Yeniden Boyutlandırılır?


336

Benim uzak veritabanı Base64 String alınan bir bitmap var ( encodedImageBase64 ile görüntü temsil eden dize):

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 benim ImageView

Tamam, ancak düzenimde göstermeden önce bu resmi yeniden boyutlandırmam gerekiyor ImageView. 120x120 olarak yeniden boyutlandırmam gerekiyor.

Birisi bana kodu yeniden boyutlandırmasını söyleyebilir mi?

Bulduğum örnekler, elde edilen bir base64 dizgisine uygulanamadı.


Yanıtlar:


550

Değişiklik:

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

Kime:

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

1200x1200 gibi büyük çözünürlüklü bir resminiz olduğunu varsayalım ve bunu görüntülediğinizde, görüntüleme görüntüsünde dolu olacaktır. Aşağı doğru% 75 diyelim ve ekran ölçeklendirilmiş görüntüyü tam olarak görüntü görünümünde gösterecek şekilde ise, bu tür ekranlar için ne yapılmalı?
jxgn

5
CreateScaledBitmap, Galaxy Tab2'mde çok fazla bellek olduğundan ve başka hiçbir özel uygulamanın çalışmadığı için benim için çok garip bir Bellek Dışı İstisnası atıyor. Matrix çözümü de işe yarıyor.
Ludovic

28
en boy oranını kaydetmek istiyorsak ??
Böcekler

3
Bunun için dpi ölçeklendirmesine ne dersiniz? Ölçekli bitmap'in cihazın ekran yüksekliğine ve genişliğine dayanması gerektiğini düşünüyorum?
Doug Ray

2
Görüntünün orijinal boyutunun yarısından fazlasını küçültmek için Bitmap.createScaledBitmap () kullanılması, diğer adlandırma yapıları oluşturabilir. Bir bakmak olabilir mesaja bazı alternatifler öne ve kalite ve performansı karşılaştırmak nerede yazdım.
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: @aveschini tarafından önerildiği gibi, bm.recycle();bellek sızıntıları için ekledim . Önceki nesneyi başka amaçlar için kullanıyorsanız, buna göre işlem yapın.


6
Hem bitmap.createscaledbitmap'i hem de bu matris yaklaşımını denedim. Matris yaklaşımıyla görüntünün çok daha net olduğunu düşünüyorum. Yaygın olup olmadığını bilmiyorum ya da sadece telefon yerine bir simülatör kullanıyorum. Benim gibi aynı sorunu kodlayan biri için bir ipucu.
Anson Yao

2
burada da çok daha iyi bellek performansları için bm.recycle () eklemek zorundasınız
aveschini

2
Çözüm için teşekkürler, ancak parametrelerin yeniden sıralanması daha iyi olurdu; public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight). Bunu anlamak için çok zaman harcadım. ; P
Saldırgan

1
Matrix için doğru içe aktarmanın android.graphics.Matrix olduğunu unutmayın.
Lev

11
Bu, Bitmap.createScaledBitmap () öğesini çağırmakla aynıdır. Bkz android.googlesource.com/platform/frameworks/base/+/refs/heads/...
BamsBamx

122

Zaten bir bitmap'iniz varsa, yeniden boyutlandırmak için aşağıdaki kodu kullanabilirsiniz:

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

1
@beginner, görüntüyü yeniden boyutlandırırsanız, bitmap'i yanlış oranlara dönüştüren veya bazı bitmap bilgilerini kaldıran farklı boyutlara dayalı olarak ölçekleme yapıyor olabilirsiniz.
ZenBalance

Bitmap'i oranlara göre yeniden boyutlandırmayı denedim, ancak sonra bu hatayı alıyordum. Neden: java.lang.RuntimeException: Tuval: geri dönüştürülmüş bir bitmap kullanmaya çalışıyor android.graphics.Bitmap@2291dd13
acemi

@ yeni bitmap'i her yeniden boyutlandırdığınızda, ne yaptığınıza bağlı olarak, mevcut bitmap'i yeniden boyutlandırmak yerine genellikle yeni boyutta bir kopya oluşturmanız gerekir (çünkü bu durumda bitmap referansı zaten bellekte geri dönüştürülmüş).
ZenBalance

1
doğru .. ben denedim ve şimdi düzgün çalışıyor. teşekkürler
acemi

39

En boy oranına göre ölçeklendirme :

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

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

Yüksekliği genişliğin temel amacı olarak kullanmak için şu şekilde değiştirin:

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

24

En boy oranını korurken, bir bitmap'i hedef maksimum boyut ve genişlikle ölçeklendirin:

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

bu kodu deneyin:

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

Umarım faydalıdır.


7

Birisi bu durumda en boy oranını nasıl koruyacağını sordu:

Ölçekleme için kullandığınız faktörü hesaplayın ve her iki boyut için de kullanın. Bir görüntünün ekranın% 20 yüksekliğinde olmasını istediğinizi varsayalım

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

ekran çözünürlüğünü elde etmek için şu çözüme sahipsiniz: Ekran boyutlarını piksel olarak alın


3

Bunu deneyin: Bu işlev bir bitmap'i orantılı olarak yeniden boyutlandırır. Son parametre "X" newDimensionXorYolarak ayarlandığında, yeni genişlik olarak kabul edilir ve "Y" olarak ayarlandığında yeni bir yükseklik elde edilir.

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

benim için biraz yeniden float şamandıra sonra çalıştı oversSizeRatio = width> height? (şamandıra) ((şamandıra) genişlik / (şamandıra) ScaleSize): (şamandıra) ((şamandıra) yükseklik / (şamandıra) 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

Herhangi bir Ekran boyutuna göre Bitmap Yeniden Boyutlandırma

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

Kabul edilen cevap doğru olmasına rağmen, Bitmapaynı En Boy Oranı korunarak yeniden boyutlandırılmaz . BitmapAynı en boy oranını koruyarak yeniden boyutlandırmak için bir yöntem arıyorsanız , aşağıdaki yardımcı program işlevini kullanabilirsiniz. Kullanım ayrıntıları ve işlevin açıklaması bu bağlantıda bulunmaktadır .

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

En boy oranını koruyarak,

  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;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.