Как преобразовать изображение в строку Base64?
Может кто-нибудь сказать мне код для преобразования изображения (максимум 200 КБ) в Base64 String?
Мне нужно знать, как это сделать с Android, потому что я должен добавить функцию загрузки изображений на удаленный сервер в моем главном приложении, помещая их в строку базы данных в виде строки.
Я ищу в Google и в Stackru, но не могу найти простых примеров, которые могу себе позволить, а также я нахожу некоторые примеры, но они не говорят о том, чтобы преобразовать в String. Затем мне нужно преобразовать в строку для загрузки с помощью JSON на мой удаленный сервер.
18 ответов
Вы можете использовать Base64 Android класс:
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
Вы должны будете преобразовать ваше изображение в байтовый массив. Вот пример:
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();
* Обновить *
Если вы используете старую библиотеку SDK (потому что вы хотите, чтобы она работала на телефонах с более старыми версиями ОС), у вас не будет упакован класс Base64 (так как он только что вышел в API уровня 8 или версии 2.2).
Проверьте эту статью для обхода:
http://androidcodemonkey.blogspot.com/2010/03/how-to-base64-encode-decode-android.html
Вместо того, чтобы использовать Bitmap
Вы также можете сделать это через тривиальное InputStream
, Ну, я не уверен, но я думаю, что это немного эффективно
InputStream inputStream = new FileInputStream(fileName);//You can get an inputStream using any IO 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);
Если вам нужно base64 поверх JSON, проверьте Джексона: он имеет явную поддержку чтения / записи двоичных данных как base64 как на низком уровне (JsonParser, JsonGenerator), так и на уровне привязки данных. Таким образом, вы можете просто иметь POJO со свойствами byte[], и кодирование / декодирование выполняется автоматически. И довольно эффективно, если это имеет значение.
Вот код кодирования и декодирования в Котлине:
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)
}
// 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;
}
Если вы делаете это на Android, вот помощник, скопированный из базы кода 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) {
}
}
Этот префект кода запускается в моем проекте
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 base 64 string
String imgString = Base64.encodeToString(byteFormat, Base64.NO_WRAP);
return imgString;
}
Для тех, кто ищет эффективный метод преобразования файла изображения в строку Base64 без сжатия или сначала преобразования файла в растровое изображение, вы можете вместо этого кодировать файл как base64
val base64EncodedImage = FileInputStream(imageItem.localSrc).use {inputStream - >
ByteArrayOutputStream().use {outputStream - >
Base64OutputStream(outputStream, Base64.DEFAULT).use {
base64FilterStream - >
inputStream.copyTo(base64FilterStream)
base64FilterStream.flush()
outputStream.toString()
}
}
}
Надеюсь это поможет!
Версия Котлина:
fun File.toBase64(): String? {
val result: String?
inputStream().use { inputStream ->
val sourceBytes = inputStream.readBytes()
result = Base64.encodeToString(sourceBytes, Base64.DEFAULT)
}
return result
}
Другой способ написания на Котлине, более простой:
fun imageBase64(filepath: String): String {
FileInputStream(filepath).use {
val bytes = it.readBytes()
return Base64.encodeToString(bytes, Base64.DEFAULT)
}
}
Преобразование изображения в строку base64 в 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);
Ниже приведен псевдокод, который может вам помочь:
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;
}
Вот код для кодирования и декодирования изображений.
В файле XML
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="yyuyuyuuyuyuyu"
android:id="@+id/tv5"
/>
В файле 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();
В Kotlin вы можете просто использовать функцию декодирования для byteArray...
private fun stringToBitmap(encodedString: String): Bitmap {
val imageBytes = decode(encodedString, DEFAULT)
return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
}
Я делаю статическую функцию. Я думаю, это более эффективно.
public static String file2Base64(String filePath) {
FileInputStream fis = null;
String base64String = "";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
fis = new FileInputStream(filePath);
byte[] buffer = new byte[1024 * 100];
int count = 0;
while ((count = fis.read(buffer)) != -1) {
bos.write(buffer, 0, count);
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
base64String = Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
return base64String;
}
Просто и проще!
для кодирования
private String encodeImage(Bitmap bitmap){
int previewWidth=150;
int previewHeight=bitmap.getHeight()*previewWidth/ bitmap.getWidth();
Bitmap previewBitmap = Bitmap.createScaledBitmap(bitmap,previewWidth,previewHeight,false);
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
previewBitmap.compress(Bitmap.CompressFormat.JPEG,50,byteArrayOutputStream);
byte[] bytes=byteArrayOutputStream.toByteArray();
return Base64.encodeToString(bytes,Base64.DEFAULT);
}
private final ActivityResultLauncher<Intent> pickImage=registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode()==RESULT_OK){
if (result.getData()!=null){
Uri imageuri=result.getData().getData();
try{
InputStream inputStream= getContentResolver().openInputStream(imageuri);
Bitmap bitmap= BitmapFactory.decodeStream(inputStream);
binding.imageProfile.setImageBitmap(bitmap);
encodedImage= encodeImage(bitmap);
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
}
);
byte[] decodedString = Base64.decode(result.getBytes(), Base64.DEFAULT);
Используйте этот код:
byte[ ] decodedString = Base64.decode(Base64String.getBytes(), Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);