Android растровое изображение в строку Base64


Как преобразовать большое растровое изображение (фото, сделанное с помощью камеры телефона) в строку Base64?

4 88

4 ответа:

используйте следующий метод для преобразования растрового изображения в массив байтов:

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

для кодирования base64 из массива байтов используйте следующий метод

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

у меня есть быстрое решение. Просто создайте файл ImageUtil.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);
    }

}

использование:

Bitmap bitmap = ImageUtil.convert(base64String);

или

String base64String = ImageUtil.convert(bitmap);

проблема с ответом Джита заключается в том, что вы загружаете все байты изображения в массив байтов, что, скорее всего, приведет к сбою приложения на бюджетных устройствах. Вместо этого я бы сначала записал изображение в файл и прочитал его с помощью Apache Base64InputStream класса. Затем вы можете создать строку Base64 непосредственно из входного потока этого файла. Это будет выглядеть так:

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

Как вы можете видеть, вышеуказанное решение работает непосредственно с потоками вместо этого, избегая необходимости загрузите все байты в переменную, что значительно снизит объем памяти и уменьшит вероятность сбоя в низкоуровневых устройствах. По-прежнему существует проблема, что помещение самой строки Base64 в строковую переменную не является хорошей идеей, потому что, опять же, это может вызвать ошибки OutOfMemory. Но, по крайней мере, мы сократили потребление памяти наполовину, исключив массив байтов.

Если вы хотите пропустить шаг записи в файл, вы должны преобразовать OutputStream в InputStream, что не так просто сделать (вы должны использовать PipedInputStream но это немного сложнее, так как два потока всегда должно быть в разных потоках).

попробуйте это, сначала масштабируйте изображение до требуемой ширины и высоты, просто передайте исходное растровое изображение, требуемую ширину и требуемую высоту в следующий метод и получите масштабированное растровое изображение взамен:

например: 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);
}

Теперь просто передайте масштабированное растровое изображение в следующий метод и получите строку base64 в ответ:

например: строка 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 обратно в растровое изображение:

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