Android Bitmap'den Base64 String'e


128

Büyük bir Bitmap'i (telefonun kamerasıyla çekilen fotoğraf) Base64 String'e nasıl dönüştürebilirim?


Görüntüyü nasıl kodlamak istersiniz?
Ted Hopp

Yanlış soruyu soruyorsun. Telefonun kamerasıyla çekilen fotoğraflar bitmapler değil jpeg olarak kaydedilir. Yalnızca jpeg'i görüntülemek için bit eşlem olarak çözmeniz gerekir. Aşağıdaki cevabımı izlerseniz daha az OutOfMemory hatası ve gereksiz işleminiz olacak.
Carson Holzheimer

Yanıtlar:


301

bitmap'i bayt dizisine dönüştürmek için aşağıdaki yöntemi kullanın:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();

bayt dizisinden base64 kodlamak için aşağıdaki yöntemi kullanın

String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);

Çözüm için teşekkürler, aynı kodu kullandım ama kodlanmış dizem ... sonunda ve tamamen dönüştürülmediğini düşünüyorum, bu yüzden lütfen bana neden Base 64 dizesinin sonunda noktalar olduğunu söyleyin (...) ..
Pankaj Singh

@Pankaj Merhaba, bu sorunu nasıl çözdüğünüzü söyleyebilir misiniz, kodlanmış dizimde aynı sorunla karşılaşıyorum 3 nokta var (...) bunu çözmek için lütfen yardım edebilir misiniz
Sachin Gurnani

5
@SachinGurnani - gösteriyor ... çünkü logcat sınırlı String uzunluğu gösteriyor ve bundan sonra kesilmiş. bu yüzden.
Pankaj Singh

Yanıtınız için teşekkürler Pankaj. bu konuyu aynı gün
kendim inceledim

1
bu asenkron görevde yapılmalı mı? yoksa bunu ana ileti dizisinde yapmak doğru mu?
n3wb

28

Hızlı bir çözümüm var. Sadece bir dosya oluşturunImageUtil.java

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;

public class ImageUtil
{
    public static Bitmap convert(String base64Str) throws IllegalArgumentException
    {
        byte[] decodedBytes = Base64.decode(
            base64Str.substring(base64Str.indexOf(",")  + 1),
            Base64.DEFAULT
        );

        return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
    }

    public static String convert(Bitmap bitmap)
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);

        return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
    }

}

Kullanımı:

Bitmap bitmap = ImageUtil.convert(base64String);

veya

String base64String = ImageUtil.convert(bitmap);

13

Jeet'in cevabıyla ilgili sorun, görüntünün tüm baytlarını bir bayt dizisine yüklemenizdir, bu da muhtemelen uygulamanın düşük kaliteli cihazlarda çökmesine neden olacaktır. Bunun yerine, önce görüntüyü bir dosyaya yazar ve Apache'nin Base64InputStream sınıfını kullanarak okurum . Ardından, Base64 dizesini doğrudan o dosyanın InputStream öğesinden oluşturabilirsiniz. Bunun gibi görünecek:

//Don't forget the manifest permission to write files
final FileOutputStream fos = new FileOutputStream(yourFileHere); 
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

fos.close();

final InputStream is = new Base64InputStream( new FileInputStream(yourFileHere) );

//Now that we have the InputStream, we can read it and put it into the String
final StringWriter writer = new StringWriter();
IOUtils.copy(is , writer, encoding);
final String yourBase64String = writer.toString();

Gördüğünüz gibi, yukarıdaki çözüm doğrudan bunun yerine akışlarla çalışır ve tüm baytları bir değişkene yükleme ihtiyacını ortadan kaldırır, bu nedenle bellek ayak izini çok daha düşük ve düşük kaliteli cihazlarda çökme olasılığını azaltır. Hala Base64 dizesinin kendisini bir String değişkenine koymanın iyi bir fikir olmaması sorunu var, çünkü yine, OutOfMemory hatalarına neden olabilir. Ama en azından bayt dizisini ortadan kaldırarak bellek tüketimini yarı yarıya azalttık.

Bir dosyaya yazma adımını atlamak istiyorsanız, OutputStream'i bir InputStream'e dönüştürmeniz gerekir ki bu çok kolay değildir ( PipedInputStream kullanmanız gerekir, ancak bu iki akış her zaman olması gerektiğinden biraz daha karmaşıktır. farklı konularda olun).


2
Burada kodlama nedir?
Animesh Mangla

5

Bunu deneyin, önce görüntünüzü gerekli genişlik ve yüksekliğe ölçekleyin, orijinal bitmapinizi, gerekli genişliği ve yüksekliği aşağıdaki yönteme geçirin ve karşılığında ölçeklenmiş bitmap alın:

Örneğin: Bitmap scaledBitmap = getScaledBitmap (originalBitmap, 250, 350);

private Bitmap getScaledBitmap(Bitmap b, int reqWidth, int reqHeight)
{
    int bWidth = b.getWidth();
    int bHeight = b.getHeight();

    int nWidth = bWidth;
    int nHeight = bHeight;

    if(nWidth > reqWidth)
    {
        int ratio = bWidth / reqWidth;
        if(ratio > 0)
        {
            nWidth = reqWidth;
            nHeight = bHeight / ratio;
        }
    }

    if(nHeight > reqHeight)
    {
        int ratio = bHeight / reqHeight;
        if(ratio > 0)
        {
            nHeight = reqHeight;
            nWidth = bWidth / ratio;
        }
    }

    return Bitmap.createScaledBitmap(b, nWidth, nHeight, true);
}

Şimdi ölçeklenmiş bitmap'inizi aşağıdaki yönteme iletin ve karşılığında base64 dizesini alın:

Örneğin: String base64String = getBase64String (scaledBitmap);

private String getBase64String(Bitmap bitmap)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

    byte[] imageBytes = baos.toByteArray();

    String base64String = Base64.encodeToString(imageBytes, Base64.NO_WRAP);

    return base64String;
}

Base64 dizesinin kodunu bitmap görüntüsüne geri çözmek için:

byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);

3

Bu yanıtların tümü, bir bitmap'e gereksiz yere kodu çözdükleri ve ardından bitmap'i yeniden sıkıştırdıkları için verimsizdir. Android'de bir fotoğraf çektiğinizde , android belgelerini takip ettiğinizde belirttiğiniz geçici dosyada jpeg olarak saklanır .

Yapmanız gereken, bu dosyayı doğrudan bir Base64 dizesine dönüştürmektir. İşte bunu kolay kopyala-yapıştır ile nasıl yapacağınız (Kotlin'de). Dahili tamponunu gerçekten boşaltmak için base64FilterStream'i kapatmanız gerektiğini unutmayın.

fun convertImageFileToBase64(imageFile: File): String {

    return FileInputStream(imageFile).use { inputStream ->
        ByteArrayOutputStream().use { outputStream ->
            Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
                inputStream.copyTo(base64FilterStream)
                base64FilterStream.close()
                outputStream.toString()
            }
        }
    }
}

Bonus olarak, yeniden sıkıştırmayı atlamanız nedeniyle görüntü kaliteniz biraz iyileştirilmelidir.


1

Artık çoğu insan Java yerine Kotlin kullandığına göre, Kotlin'de bir bitmap'i base64 dizesine dönüştürmek için kullanılan kod burada.

import java.io.ByteArrayOutputStream

private fun encodeImage(bm: Bitmap): String? {
        val baos = ByteArrayOutputStream()
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
        val b = baos.toByteArray()
        return Base64.encodeToString(b, Base64.DEFAULT)
    }

-2

Bu kodu kullanın ..

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;

public class ImageUtil 
{ 
    public static Bitmap convert(String base64Str) throws IllegalArgumentException 
    { 
        byte[] decodedBytes = Base64.decode( base64Str.substring(base64Str.indexOf(",") + 1), Base64.DEFAULT );
        return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
    } 

    public static String convert(Bitmap bitmap) 
    { 
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
        return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
    }
}
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.