Wie kann ich die Größe einer Bitmap in Android ändern?

336

Ich habe eine Bitmap eines Base64- encodedImageStrings aus meiner entfernten Datenbank ( ist der String, der das Image mit Base64 darstellt):

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 ist meine ImageView

Ok, aber ich muss die Größe dieses Bildes ändern, bevor ich es ImageViewin meinem Layout anzeigen kann. Ich muss die Größe auf 120x120 ändern.

Kann mir jemand den Code sagen, um die Größe zu ändern?

Die gefundenen Beispiele konnten nicht auf eine Bitmap mit Base64-Zeichenfolge angewendet werden.

NullPointerException
quelle
Mögliches Duplikat von Resize Bitmap in Android
Sagar Pilkhwal

Antworten:

550

Veränderung:

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

Zu:

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));
user432209
quelle
Angenommen, Sie haben ein Bild mit hoher Auflösung, z. B. 1200 x 1200, und wenn Sie dies anzeigen, ist es in der Bildansicht voll. Wenn ich es verkleinere, sagen wir 75%, und der Bildschirm so ist, dass das skalierte Bild auch vollständig in der Bildansicht angezeigt wird, was sollte für solche Bildschirme getan werden?
jxgn
5
Die createScaledBitmap löst auf meinem Galaxy Tab2 eine Ausnahme wegen Speichermangels aus, was für mich sehr seltsam ist, da viel Speicher vorhanden ist und keine andere bestimmte App ausgeführt wird. Die Matrix-Lösung funktioniert jedoch.
Ludovic
28
Was ist, wenn wir das Seitenverhältnis speichern möchten?
Bugs passieren am
3
Was ist mit der dpi-Skalierung dafür? Ich denke, die skalierte Bitmap sollte auf der Höhe und Breite des Gerätebildschirms basieren.
Doug Ray
2
Die Verwendung von Bitmap.createScaledBitmap () zum Verkleinern eines Bildes, das mehr als die Hälfte der Originalgröße beträgt, kann zu Aliasing-Artefakten führen. Sie können sich einen Beitrag ansehen, in dem ich einige Alternativen vorschlage und Qualität und Leistung vergleiche.
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;
}

BEARBEITEN: Wie von @aveschini vorgeschlagen, habe ich bm.recycle();für Speicherlecks hinzugefügt . Bitte beachten Sie, dass Sie, wenn Sie das vorherige Objekt für andere Zwecke verwenden, entsprechend vorgehen müssen.

jeet.chanchawat
quelle
6
Ich habe sowohl bitmap.createscaledbitmap als auch diesen Matrix-Ansatz ausprobiert. Ich finde, dass das Bild mit dem Matrix-Ansatz viel klarer ist. Ich weiß nicht, ob es üblich ist oder nur, weil ich einen Simulator anstelle eines Telefons verwende. Nur ein Hinweis für jemanden, der die gleichen Probleme wie ich hat.
Anson Yao
2
Auch hier müssen Sie bm.recycle () für viel bessere Speicherleistungen hinzufügen
aveschini
2
Vielen Dank für die Lösung, aber es wäre besser, wenn die Parameter neu angeordnet würden. public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight). Ich habe verdammt viel Zeit damit verbracht, es herauszufinden. ; P
Attacktive
1
Beachten Sie, dass der korrekte Import für Matrix android.graphics.Matrix ist.
Lev
11
Dies entspricht dem Aufruf von Bitmap.createScaledBitmap (). Siehe android.googlesource.com/platform/frameworks/base/+/refs/heads/…
BamsBamx
122

Wenn Sie bereits eine Bitmap haben, können Sie die Größe des folgenden Codes verwenden:

Bitmap originalBitmap = <original initialization>;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
    originalBitmap, newWidth, newHeight, false);
ZenBalance
quelle
1
@beginner Wenn Sie die Bildgröße ändern, skalieren Sie möglicherweise basierend auf verschiedenen Dimensionen, die entweder die Bitmap in falsche Proportionen umwandeln oder einige der Bitmap-Informationen entfernen.
ZenBalance
Ich habe versucht, die Größe der Bitmap basierend auf den Proportionen zu ändern, aber dann wurde dieser Fehler angezeigt. Auslöser: java.lang.RuntimeException: Canvas: Versuch, eine recycelte Bitmap zu verwenden android.graphics.Bitmap@2291dd13
Anfänger
@beginner Jedes Mal, wenn Sie die Größe der Bitmap ändern, müssen Sie in der Regel eine Kopie mit einer neuen Größe erstellen, anstatt die Größe der vorhandenen Bitmap zu ändern (da in diesem Fall der Verweis auf die Bitmap so aussieht bereits im Speicher recycelt).
ZenBalance
1
richtig .. ich habe es versucht und es funktioniert jetzt richtig. danke
Anfänger
39

Skala basierend auf dem Seitenverhältnis :

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

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

Um die Höhe als Basis anstelle der Breite zu verwenden, ändern Sie zu:

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

Skalieren Sie eine Bitmap mit einer maximalen Zielgröße und -breite unter Beibehaltung des Seitenverhältnisses:

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
quelle
7

Versuchen Sie diesen Code:

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

Ich hoffe es ist nützlich.

Ravi Makvana
quelle
7

Jemand fragte, wie das Seitenverhältnis in dieser Situation beibehalten werden soll:

Berechnen Sie den Faktor, den Sie für die Skalierung verwenden, und verwenden Sie ihn für beide Dimensionen. Angenommen, Sie möchten, dass ein Bild 20% der Bildschirmhöhe hat

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

Um die Bildschirmauflösung zu erhalten, haben Sie folgende Lösung: Abrufen der Bildschirmabmessungen in Pixel

Taochok
quelle
3

Versuchen Sie Folgendes: Diese Funktion ändert die Größe einer Bitmap proportional. Wenn der letzte Parameter auf "X" gesetzt newDimensionXorYist, wird dies als neue Breite und bei "Y" als neue Höhe behandelt.

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;
}
user2288580
quelle
3
profileImage.setImageBitmap(
    Bitmap.createScaledBitmap(
        BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length), 
        80, 80, false
    )
);
Rajkamal
quelle
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.
quelle
für mich hat es nach einigem retyping float floatSizeRatio = width> height funktioniert? (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
quelle
2

Bitmap-Größe basierend auf einer beliebigen Anzeigegröße

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
quelle
1

Obwohl die akzeptierte Antwort korrekt ist, wird die Größe nicht geändert, Bitmapindem das gleiche Seitenverhältnis beibehalten wird . Wenn Sie nach einer Methode suchen, deren Größe Bitmapbei gleichem Seitenverhältnis geändert werden kann, können Sie die folgende Dienstprogrammfunktion verwenden. Die Verwendungsdetails und Erläuterungen zur Funktion finden Sie unter diesem Link .

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
quelle
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
quelle
0

Das Seitenverhältnis beibehalten,

  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
quelle