Android Bitmap đến Chuỗi Base64


128

Làm cách nào để chuyển đổi một Bitmap lớn (ảnh được chụp bằng máy ảnh của điện thoại) thành Chuỗi Base64?


Bạn muốn mã hóa hình ảnh như thế nào?
Ted Hopp

Bạn đang hỏi sai câu hỏi. Ảnh chụp bằng camera của điện thoại được lưu dưới dạng jpeg, không phải ảnh bitmap. Bạn chỉ cần giải mã jpeg thành bitmap cho mục đích hiển thị nó. Bạn sẽ có ít lỗi OutOfMemory và xử lý không cần thiết nếu bạn làm theo câu trả lời của tôi dưới đây.
Carson Holzheimer

Câu trả lời:


301

sử dụng phương pháp sau để chuyển bitmap thành mảng byte:

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

để mã hóa base64 từ mảng byte sử dụng phương thức sau

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

Cảm ơn giải pháp, tôi đã sử dụng cùng một mã nhưng chuỗi mã hóa của tôi đã ... cuối cùng và tôi nghĩ rằng nó không được chuyển đổi hoàn toàn vì vậy xin vui lòng cho tôi biết tại sao cuối chuỗi Base 64 là các dấu chấm (...) ..
Pankaj Singh

@Pankaj Xin chào, bạn có thể cho tôi biết cách bạn giải quyết vấn đề đó không, tôi đang đối mặt với cùng một vấn đề trong chuỗi được mã hóa của tôi có 3 dấu chấm (...) bạn có thể vui lòng giúp giải quyết vấn đề đó không
Sachin Gurnani

5
@SachinGurnani - nó hiển thị ... bởi vì logcat hiển thị Chuỗi giới hạn thứ mười và sau đó bị cắt ngắn. đó là lý do tại sao.
Pankaj Singh

Cảm ơn bạn đã phản hồi Pankaj. tôi đã giải quyết vấn đề này vào cùng một ngày
Sachin Gurnani

1
điều này nên được thực hiện trong asynctask? hoặc nó là tốt để làm điều này trong chủ đề chính?
n3wb

28

Tôi có giải pháp nhanh. Chỉ cần tạo một tập tinImageUtil.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);
    }

}

Sử dụng:

Bitmap bitmap = ImageUtil.convert(base64String);

hoặc là

String base64String = ImageUtil.convert(bitmap);

13

Vấn đề với câu trả lời của jeet là bạn tải tất cả các byte của hình ảnh vào một mảng byte, điều này có thể sẽ làm sập ứng dụng trong các thiết bị cấp thấp. Thay vào đó, trước tiên tôi sẽ ghi hình ảnh vào một tệp và đọc nó bằng lớp Base64InputStream của Apache . Sau đó, bạn có thể tạo chuỗi Base64 trực tiếp từ InputStream của tệp đó. Nó sẽ trông giống thế này:

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

Như bạn có thể thấy, giải pháp trên hoạt động trực tiếp với các luồng thay vào đó, tránh việc phải tải tất cả các byte vào một biến, do đó làm cho dung lượng bộ nhớ thấp hơn nhiều và ít có khả năng bị sập trong các thiết bị cấp thấp. Vẫn còn vấn đề là việc tự đặt chuỗi Base64 vào biến String không phải là ý hay, bởi vì, một lần nữa, nó có thể gây ra lỗi OutOfMemory. Nhưng ít nhất chúng ta đã giảm mức tiêu thụ bộ nhớ xuống một nửa bằng cách loại bỏ mảng byte.

Nếu bạn muốn bỏ qua bước ghi vào tệp, bạn phải chuyển đổi OutputStream thành InputStream, điều này không đơn giản để làm (bạn phải sử dụng PipedInputStream nhưng điều đó phức tạp hơn một chút vì hai luồng phải luôn luôn phức tạp được trong các chủ đề khác nhau).


2
Mã hóa ở đây là gì?
Animesh Mangla

5

Hãy thử điều này, trước tiên hãy chia tỷ lệ hình ảnh của bạn thành chiều rộng và chiều cao yêu cầu, chỉ cần chuyển bitmap gốc của bạn, chiều rộng yêu cầu và chiều cao cần thiết cho phương thức sau và nhận lại bitmap tỷ lệ:

Ví dụ: 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);
}

Bây giờ chỉ cần truyền bitmap tỷ lệ của bạn cho phương thức sau và nhận lại chuỗi base64:

Ví dụ: Chuỗi 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;
}

Để giải mã chuỗi base64 trở lại hình ảnh bitmap:

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

3

Tất cả các câu trả lời này đều không hiệu quả vì chúng không cần giải mã thành bitmap và sau đó giải nén lại bitmap. Khi bạn chụp ảnh trên Android, nó được lưu dưới dạng jpeg trong tệp tạm thời mà bạn chỉ định khi bạn theo tài liệu Android .

Những gì bạn nên làm là trực tiếp chuyển đổi tập tin đó thành chuỗi Base64. Đây là cách để làm điều đó trong bản sao chép dễ dàng (trong Kotlin). Lưu ý rằng bạn phải đóng base64FilterStream để thực sự xóa bộ đệm bên trong của 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()
            }
        }
    }
}

Là một phần thưởng, chất lượng hình ảnh của bạn sẽ được cải thiện một chút, do bỏ qua việc nén lại.


1

Bây giờ hầu hết mọi người sử dụng Kotlin thay vì Java, đây là mã trong Kotlin để chuyển đổi một bitmap thành chuỗi base64.

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

Sử dụng mã này ..

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