Jak mogę przekonwertować obraz na ciąg Base64?


143

Jaki jest kod do przekształcenia obrazu (maksymalnie 200 KB) na ciąg Base64?

Muszę wiedzieć, jak to zrobić z Androidem, ponieważ muszę dodać funkcję przesyłania obrazów na zdalny serwer w mojej głównej aplikacji, umieszczając je w wierszu bazy danych jako ciąg.

Szukam w Google i Stack Overflow, ale nie mogłem znaleźć łatwych przykładów, na które mnie stać, a także znajduję kilka przykładów, ale nie mówią o przekształceniu w String. Następnie muszę przekształcić w ciąg znaków do przesłania przez JSON na mój zdalny serwer.

Odpowiedzi:


330

Możesz użyć klasy Base64 dla systemu Android:

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

Będziesz musiał jednak przekonwertować obraz na tablicę bajtów. Oto przykład:

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

* Aktualizacja *

Jeśli używasz starszej biblioteki SDK (ponieważ chcesz, aby działała na telefonach ze starszymi wersjami systemu operacyjnego), nie będziesz mieć zapakowanej klasy Base64 (ponieważ właśnie wyszła na poziomie API 8 AKA w wersji 2.2).

Zapoznaj się z tym artykułem, aby uzyskać obejście:

Jak dekodować kodowanie base64 w systemie Android


ok, i mogę umieścić ten ciąg (encondedImage) w kolumnie zdalnej bazy danych z PHP + JSON ???? który typ musi być kolumną bazy danych? VARCHAR?
NullPointerException

Cóż, z VARCHAR musisz określić, jak duży byłby, więc może TEXT byłby lepszy. Obraz może mieć dowolny zakres rozmiarów ...
xil3

Cześć, testuję to, ale daje mi BŁĄD w Base64. To nie może oznaczać klasy. Wykonuję Ctrl + Shift + O, aby uzyskać import, ale nie otrzymuje importu ... ¿jak to rozwiązać?
NullPointerException,

4
U mnie działało po zamianie: String encodedImage = Base64.encode (byteArrayImage, Base64.DEFAULT); Przez: String encodedImage = Base64.encodeToString (byteArrayImage, Base64.DEFAULT);
PakitoV,

3
Czy ktoś zdaje sobie sprawę, że ta metoda powoduje bezsensowną kompresję pliku? dlaczego jest to tak uprzywilejowane ?? Odpowiedź Chandry Sekhar jest najbardziej skuteczna.
ElYeante,

103

Zamiast używać Bitmap, możesz to również zrobić za pomocą trywialnego pliku InputStream. Cóż, nie jestem pewien, ale myślę, że to trochę wydajne.

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

3
Oczywiście jest to bardziej wydajne; po prostu przekształca plik w jego reprezentację base64 i unika absolutnie bezsensownej ponownej kompresji obrazu.
ElYeante

to nazwa_pliku tutaj ścieżka do pliku lub rzeczywista nazwa pliku ??? Nie zapomnij oznaczyć mnie tagiem :) Dzięki.
Rakeeb Rajbhandari

2
@ user2247689 Gdy próbujesz uzyskać dostęp do pliku, oczywiście musisz podać pełną ścieżkę do pliku, łącznie z jego nazwą. Jeśli plik znajduje się w tej samej ścieżce, w której znajduje się program źródłowy, wystarczy nazwa pliku.
Chandra Sekhar

2
Pytanie, co oznacza tutaj „8192”, czy jest to rozmiar pliku, czy co?
Devesh Khandelwal

1
ten kod nie działa, straciłem wiele godzin, aby dodać problem.
Ramkesh Yadav

7

Jeśli potrzebujesz Base64 przez JSON, sprawdź Jackson : ma wyraźną obsługę odczytu / zapisu danych binarnych jako Base64 zarówno na niskim poziomie (JsonParser, JsonGenerator), jak i na poziomie wiązania danych. Możesz więc mieć POJO z właściwościami byte [], a kodowanie / dekodowanie jest obsługiwane automatycznie.

I całkiem efektywnie, jeśli to ma znaczenie.


1
za trudne dla mnie, moje umiejętności są bardzo niskie, sprawdziłem to w Google i nie mogę znaleźć łatwych przykładów ... może jeśli dasz mi przykłady kodu takie jak xil3, zrozumiem to
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;
}

3

Ten kod działa idealnie w moim projekcie:

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

2

Jeśli robisz to na Androidzie , oto pomocnik skopiowany z bazy kodu 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) {
  }
}

2
(przydzieli duży ciąg i może spowodować awarię OOM) Więc jakie jest rozwiązanie w tym przypadku?
Ibrahim Disouki

1

Oto kod kodowania i dekodowania w 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)
}

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

6
Chociaż ten kod może odpowiedzieć na pytanie, zapewnia dodatkowy kontekst dotyczący tego, dlaczego i / lub jak ten kod odpowiada, poprawia jego długoterminową wartość.
Kaczor Donald

Wytłumaczenie byłoby w porządku.
Peter Mortensen

0

Poniżej znajduje się pseudokod, który może Ci pomóc:

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

0

Konwertuj obraz na ciąg Base64 w systemie 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);

0

Oto kod do kodowania i dekodowania obrazu.

W pliku XML

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

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

Czy to faktycznie się skompiluje? Pominąłeś coś?
Peter Mortensen

0

Dla tych, którzy szukają wydajnej metody konwersji pliku obrazu na ciąg Base64 bez kompresji lub najpierw konwertowania pliku na mapę bitową, możesz zamiast tego zakodować plik jako base64

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

Mam nadzieję że to pomoże!


-1

Użyj tego kodu:

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

Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);

Jest wręcz przeciwnie
Rafael Ruiz Muñoz
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.