큰 비트 맵 (휴대폰 카메라로 찍은 사진)을 Base64 문자열로 변환하려면 어떻게합니까?
큰 비트 맵 (휴대폰 카메라로 찍은 사진)을 Base64 문자열로 변환하려면 어떻게합니까?
답변:
다음 방법을 사용하여 비트 맵을 바이트 배열로 변환하십시오.
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);
jeet의 대답의 문제는 이미지의 모든 바이트를 바이트 배열로로드하는 것입니다.이 경우 저가형 장치에서 앱이 충돌 할 가능성이 있습니다. 대신 먼저 이미지를 파일에 쓰고 Apache의 Base64InputStream 클래스를 사용하여 읽습니다 . 그런 다음 해당 파일의 InputStream에서 직접 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 문자열 자체를 String 변수에 넣는 것은 좋은 생각이 아니라는 문제가 있습니다. 다시 말하지만 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 문자열을 반환합니다.
예 : String 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);
이러한 모든 답변은 불필요하게 비트 맵으로 디코딩 한 다음 비트 맵을 다시 압축하므로 비효율적입니다. Android에서 사진을 찍으면 Android 문서 를 팔로우 할 때 지정한 임시 파일에 jpeg로 저장됩니다. .
해야 할 일은 해당 파일을 Base64 문자열로 직접 변환하는 것입니다. 다음은 쉬운 복사-붙여 넣기 (Kotlin)로 수행하는 방법입니다. 내부 버퍼를 완전히 비우려면 base64FilterStream을 닫아야합니다.
fun convertImageFileToBase64(imageFile: File): String {
return FileInputStream(imageFile).use { inputStream ->
ByteArrayOutputStream().use { outputStream ->
Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
inputStream.copyTo(base64FilterStream)
base64FilterStream.close()
outputStream.toString()
}
}
}
}
보너스로 재 압축을 건너 뛰기 때문에 이미지 품질이 약간 향상되어야합니다.
이제 대부분의 사람들이 Java 대신 Kotlin을 사용하므로 비트 맵을 base64 문자열로 변환하기위한 Kotlin의 코드가 있습니다.
import java.io.ByteArrayOutputStream
private fun encodeImage(bm: Bitmap): String? {
val baos = ByteArrayOutputStream()
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val b = baos.toByteArray()
return Base64.encodeToString(b, Base64.DEFAULT)
}
이 코드를 사용하십시오 ..
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);
}
}