Como posso converter uma imagem em uma string Base64?

143

Qual é o código para transformar uma imagem (máximo de 200 KB) em uma String Base64?

Preciso saber como fazer isso com o Android, porque tenho que adicionar a funcionalidade para fazer upload de imagens em um servidor remoto no meu aplicativo principal, colocando-as em uma linha do banco de dados, como uma sequência.

Estou pesquisando no Google e no Stack Overflow, mas não consegui encontrar exemplos fáceis que eu possa pagar e também encontro alguns exemplos, mas eles não estão tentando transformar em String. Então eu preciso me transformar em uma string para fazer upload por JSON no meu servidor remoto.

Null Pointer Exception
fonte

Respostas:

331

Você pode usar a classe Android Base64:

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

Você terá que converter sua imagem em uma matriz de bytes. Aqui está um exemplo:

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

* Atualização *

Se você estiver usando uma biblioteca SDK mais antiga (porque deseja que ela funcione em telefones com versões mais antigas do sistema operacional), não terá a classe Base64 empacotada (uma vez que ela acabou de sair no nível 8 da API AKA versão 2.2).

Confira este artigo para uma solução alternativa:

Como codificar base64 decodificar Android

xil3
fonte
ok, e eles eu posso colocar essa String (encondedImage) em uma coluna de banco de dados remoto com PHP + JSON ???? que tipo deve ser a coluna do banco de dados? VARCHAR?
NullPointerException 28/01
Bem, com o VARCHAR, você precisa especificar o tamanho, para que talvez o TEXT seja melhor. A imagem pode ter vários tamanhos ...
xil3 28/01
Oi, eu estou testando, mas isso me dá erro em Base64. Não pode conter a classe. Faço Ctrl + shift + O para obter as importações, mas não obtém importações ... ¿como resolvê-lo?
NullPointerException
4
Para mim, estava trabalhando depois de substituir: String encodedImage = Base64.encode (byteArrayImage, Base64.DEFAULT); Por: String encodedImage = Base64.encodeToString (byteArrayImage, Base64.DEFAULT);
21411 PakitoV
3
Alguém sabe que esse método faz uma recompressão sem sentido do arquivo? por que isso é tão votado? A resposta de Chandra Sekhar é a mais eficiente.
ElYeante 17/10
103

Em vez de usar Bitmap, você também pode fazer isso de forma trivial InputStream. Bem, não tenho certeza, mas acho que é um pouco 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
fonte
3
Claro que isso é mais eficiente; apenas transforma um arquivo em sua representação base64 e evita uma recompressão absolutamente sem sentido da imagem.
ElYeante 17/10
é o fileName aqui, o caminho do arquivo ou o nome do arquivo real ??? Por favor, não esqueça de me marcar :) Obrigado.
Rakeeb Rajbhandari 27/11
2
@ user2247689 Quando você está tentando acessar um arquivo, obviamente precisa fornecer o caminho completo do arquivo, incluindo seu nome. Se o arquivo estiver presente no mesmo caminho em que o programa de origem está presente, o nome do arquivo será suficiente.
precisa
2
Uma pergunta, o que '8192' significa aqui, é o tamanho do arquivo ou o quê?
Devesh Khandelwal
1
esse código não está funcionando, perdi muitas horas para resolver o problema.
Ramkesh Yadav 01/02/19
7

Se você precisar do Base64 sobre JSON, confira Jackson : ele possui suporte explícito para leitura / gravação de dados binários como Base64 no nível baixo (JsonParser, JsonGenerator) e no nível de ligação de dados. Assim, você pode apenas ter POJOs com propriedades de byte [], e a codificação / decodificação é manipulada automaticamente.

E com bastante eficiência também, caso isso importe.

StaxMan
fonte
1
muito difícil para mim, minhas habilidades são muito baixos com isso, eu verifiquei no google e não é possível encontrar exemplos fáceis ... talvez se você pode me dar exemplos de código como xil3 eu vou entender isso
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
fonte
3

Este código é perfeito no meu projeto:

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
fonte
2

Se você estiver fazendo isso no Android , aqui está um auxiliar copiado da base de código do 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
fonte
2
(alocará uma cadeia grande e pode causar uma falha no OOM) Então, qual é a solução nesse caso?
Ibrahim Disouki
1

Aqui está o código de codificação e decodificação no 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
fonte
0
byte[] decodedString = Base64.decode(result.getBytes(), Base64.DEFAULT);
fdhchc
fonte
6
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo.
Donald Duck
Uma explicação estaria em ordem.
Peter Mortensen
0

Abaixo está o pseudocódigo que pode ajudá-lo:

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

Converta uma imagem em String Base64 no 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
fonte
0

Aqui está o código para codificação e decodificação de imagens.

Em um arquivo XML

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

Em um arquivo 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
fonte
Isso realmente será compilado? Você deixou algo de fora?
Peter Mortensen
0

Para aqueles que procuram um método eficiente para converter um arquivo de imagem em uma sequência Base64 sem compactar ou converter o arquivo em um bitmap primeiro, é possível codificar o arquivo 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 isto ajude!

Alessi 42
fonte
-1

Use este código:

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

Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
PJ2104
fonte
Isto é justamente o oposto #
Rafael Ruiz Muñoz