¿Cómo puedo convertir una imagen en una cadena Base64?

143

¿Cuál es el código para transformar una imagen (máximo de 200 KB) en una cadena Base64?

Necesito saber cómo hacerlo con Android, porque tengo que agregar la funcionalidad para cargar imágenes a un servidor remoto en mi aplicación principal, colocándolas en una fila de la base de datos, como una cadena.

Estoy buscando en Google y en Stack Overflow, pero no pude encontrar ejemplos fáciles que pueda pagar y también encuentro algunos ejemplos, pero no están hablando de transformarse en una Cadena. Luego, necesito transformarme en una cadena para cargar por JSON a mi servidor remoto.

Excepción de puntero nulo
fuente

Respuestas:

331

Puede usar la clase de Android Base64:

String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);

Sin embargo, tendrá que convertir su imagen en una matriz de bytes. Aquí hay un ejemplo:

Bitmap bm = BitmapFactory.decodeFile("/path/to/image.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); // bm is the bitmap object
byte[] b = baos.toByteArray();

* Actualización *

Si está utilizando una biblioteca SDK anterior (porque desea que funcione en teléfonos con versiones anteriores del sistema operativo), no tendrá la clase Base64 empaquetada (ya que acaba de salir en API nivel 8 AKA versión 2.2).

Consulte este artículo para obtener una solución alternativa:

Cómo base64 codificar decodificar Android

xil3
fuente
ok, y puedo poner esa cadena (encondedImage) en una columna de base de datos remota con PHP + JSON ???? ¿Qué tipo tiene que ser la columna de la base de datos? VARCHAR?
NullPointerException
Bueno, con VARCHAR necesita especificar qué tan grande sería, por lo que quizás TEXT sería mejor. Imagen podría ser cualquier variedad de tamaños ...
xil3
Hola, lo estoy probando pero me da ERROR en Base64. No puede determinar la clase. Hago Ctrl + shift + O para obtener las importaciones pero no las obtengo ... ¿cómo resolverlo?
NullPointerException
44
Para mí estaba trabajando después de reemplazar: String encodedImage = Base64.encode (byteArrayImage, Base64.DEFAULT); Por: Cadena encodedImage = Base64.encodeToString (byteArrayImage, Base64.DEFAULT);
PakitoV
3
¿Alguien se da cuenta de que este método hace una recompresión sin sentido del archivo? ¿Por qué es esto tan votado? La respuesta de Chandra Sekhar es la más eficiente.
ElYeante
103

En lugar de usar Bitmap, también puede hacerlo a través de un trivial InputStream. Bueno, no estoy seguro, pero creo que es un poco eficiente.

InputStream inputStream = new FileInputStream(fileName); // You can get an inputStream using any I/O API
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();

try {
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        output.write(buffer, 0, bytesRead);
    }
}
catch (IOException e) {
    e.printStackTrace();
}

bytes = output.toByteArray();
String encodedString = Base64.encodeToString(bytes, Base64.DEFAULT);
Chandra Sekhar
fuente
3
Por supuesto, esto es más eficiente; simplemente transforma un archivo en su representación base64 y evita una recompresión de la imagen absolutamente sin sentido.
ElYeante
¿Es el nombre de archivo aquí la ruta del archivo o el nombre real del archivo? Por favor no olvides etiquetarme :) Gracias.
Rakeeb Rajbhandari
2
@ user2247689 Cuando intenta acceder a un archivo, obviamente debe proporcionar la ruta completa del archivo, incluido su nombre. Si el archivo está presente en la misma ruta donde está presente su programa fuente, entonces el nombre del archivo es suficiente.
Chandra Sekhar
2
Una pregunta, ¿qué significa '8192' aquí, es el tamaño del archivo o qué?
Devesh Khandelwal
1
este código no funciona, desperdicié muchas horas mías para solucionar el problema.
Ramkesh Yadav
7

Si necesita Base64 sobre JSON, consulte Jackson : tiene soporte explícito para la lectura / escritura de datos binarios como Base64 tanto en el nivel bajo (JsonParser, JsonGenerator) como en el nivel de enlace de datos. Por lo tanto, puede tener POJO con propiedades de byte [], y la codificación / decodificación se maneja automáticamente.

Y bastante eficiente también, si eso importa.

StaxMan
fuente
1
demasiado difícil para mí, mis habilidades son muy bajas con esto, lo revisé en Google y no puedo encontrar ejemplos fáciles ... tal vez si me puede dar ejemplos de código como xil3 lo entenderé
NullPointerException
5
// Put the image file path into this method
public static String getFileToByte(String filePath){
    Bitmap bmp = null;
    ByteArrayOutputStream bos = null;
    byte[] bt = null;
    String encodeString = null;
    try{
        bmp = BitmapFactory.decodeFile(filePath);
        bos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, bos);
        bt = bos.toByteArray();
        encodeString = Base64.encodeToString(bt, Base64.DEFAULT);
    }
    catch (Exception e){
      e.printStackTrace();
    }
    return encodeString;
}
krishan kumar Sharma
fuente
3

Este código funciona perfecto en mi proyecto:

profile_image.buildDrawingCache();
Bitmap bmap = profile_image.getDrawingCache();
String encodedImageData = getEncoded64ImageStringFromBitmap(bmap);


public String getEncoded64ImageStringFromBitmap(Bitmap bitmap) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG, 70, stream);
    byte[] byteFormat = stream.toByteArray();

    // Get the Base64 string
    String imgString = Base64.encodeToString(byteFormat, Base64.NO_WRAP);

    return imgString;
}
tej shah
fuente
2

Si está haciendo esto en Android , aquí hay un ayudante copiado de la base de código React Native :

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.util.Base64;
import android.util.Base64OutputStream;
import android.util.Log;

// You probably don't want to do this with large files
// (will allocate a large string and can cause an OOM crash).
private String readFileAsBase64String(String path) {
  try {
    InputStream is = new FileInputStream(path);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Base64OutputStream b64os = new Base64OutputStream(baos, Base64.DEFAULT);
    byte[] buffer = new byte[8192];
    int bytesRead;
    try {
      while ((bytesRead = is.read(buffer)) > -1) {
        b64os.write(buffer, 0, bytesRead);
      }
      return baos.toString();
    } catch (IOException e) {
      Log.e(TAG, "Cannot read file " + path, e);
      // Or throw if you prefer
      return "";
    } finally {
      closeQuietly(is);
      closeQuietly(b64os); // This also closes baos
    }
  } catch (FileNotFoundException e) {
    Log.e(TAG, "File not found " + path, e);
    // Or throw if you prefer
    return "";
  }
}

private static void closeQuietly(Closeable closeable) {
  try {
    closeable.close();
  } catch (IOException e) {
  }
}
Martin Konicek
fuente
2
(asignará una cadena grande y puede causar un bloqueo de OOM) Entonces, ¿cuál es la solución en este caso?
Ibrahim Disouki
1

Aquí está el código de codificación y decodificación en Kotlin:

 fun encode(imageUri: Uri): String {
    val input = activity.getContentResolver().openInputStream(imageUri)
    val image = BitmapFactory.decodeStream(input , null, null)

    // Encode image to base64 string
    val baos = ByteArrayOutputStream()
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    var imageBytes = baos.toByteArray()
    val imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT)
    return imageString
}

fun decode(imageString: String) {

    // Decode base64 string to image
    val imageBytes = Base64.decode(imageString, Base64.DEFAULT)
    val decodedImage = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)

    imageview.setImageBitmap(decodedImage)
}
Sam
fuente
0
byte[] decodedString = Base64.decode(result.getBytes(), Base64.DEFAULT);
fdhchc
fuente
66
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a por qué y / o cómo este código responde a la pregunta mejora su valor a largo plazo.
Pato Donald
Una explicación estaría en orden.
Peter Mortensen
0

A continuación se muestra el pseudocódigo que puede ayudarlo:

public  String getBase64FromFile(String path)
{
    Bitmap bmp = null;
    ByteArrayOutputStream baos = null;
    byte[] baat = null;
    String encodeString = null;
    try
    {
        bmp = BitmapFactory.decodeFile(path);
        baos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        baat = baos.toByteArray();
        encodeString = Base64.encodeToString(baat, Base64.DEFAULT);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

   return encodeString;
}
vivek
fuente
0

Convierta una imagen a una cadena Base64 en Android:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.yourimage);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT);
Aftab Alam
fuente
0

Aquí hay un código para la codificación y decodificación de imágenes.

En un archivo XML

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="yyuyuyuuyuyuyu"
    android:id="@+id/tv5"
/>

En un archivo Java:

TextView textView5;
Bitmap bitmap;

textView5 = (TextView) findViewById(R.id.tv5);

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);

new AsyncTask<Void, Void, String>() {
    @Override
    protected String doInBackground(Void... voids) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
        byte[] byteFormat = stream.toByteArray();

        // Get the Base64 string
        String imgString = Base64.encodeToString(byteFormat, Base64.NO_WRAP);

        return imgString;
    }

    @Override
    protected void onPostExecute(String s) {
       textView5.setText(s);
    }
}.execute();
Asif Ali
fuente
¿Esto realmente se compilará? ¿Dejaste algo afuera?
Peter Mortensen
0

Para aquellos que buscan un método eficiente para convertir un archivo de imagen a una cadena Base64 sin compresión o convertir el archivo a un mapa de bits primero, en su lugar puede codificar el archivo como base64

val base64EncodedImage = FileInputStream(imageItem.localSrc).use {inputStream - >
    ByteArrayOutputStream().use {outputStream - >
            Base64OutputStream(outputStream, Base64.DEFAULT).use {
                base64FilterStream - >
                    inputStream.copyTo(base64FilterStream)
                base64FilterStream.flush()
                outputStream.toString()
            }
      }
}

¡Espero que esto ayude!

Alessi 42
fuente
-1

Usa este código:

byte[] decodedString = Base64.decode(Base64String.getBytes(), Base64.DEFAULT);

Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
PJ2104
fuente
Esto es todo lo contrario
Rafael Ruiz Muñoz