Android 비트 맵을 Base64 문자열로


128

큰 비트 맵 (휴대폰 카메라로 찍은 사진)을 Base64 문자열로 변환하려면 어떻게합니까?


이미지를 어떻게 인코딩 하시겠습니까?
Ted Hopp 2012

당신은 잘못된 질문을하고 있습니다. 휴대폰 카메라로 찍은 사진은 비트 맵이 아닌 jpeg로 저장됩니다. jpeg를 표시 할 목적으로 만 비트 맵으로 디코딩하면됩니다. 아래 내 대답을 따르면 OutOfMemory 오류와 불필요한 처리가 줄어들 것입니다.
Carson Holzheimer

답변:


301

다음 방법을 사용하여 비트 맵을 바이트 배열로 변환하십시오.

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();

바이트 배열에서 base64를 인코딩하려면 다음 방법을 사용하십시오.

String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);

해결해 주셔서 감사합니다. 동일한 코드를 사용했지만 인코딩 된 문자열은 ... 결국 완전히 변환되지 않은 것 같습니다. Base 64 문자열의 끝에 점 (...)이있는 이유를 알려주세요.
Pankaj 싱

@Pankaj 안녕 u가 어떻게 그 문제를 해결하는지 말해 줄 수 있니, 내 인코딩 된 문자열에서 같은 문제에 직면 한 메신저는 3 개의 점 (...)을 가지고 있습니다. 그 문제를 해결하는 데 도움을주세요
Sachin Gurnani

5
@SachinGurnani-logcat이 제한된 문자열 길이를 표시하고 그 후에는 잘려서 표시됩니다. 그게 이유입니다.
Pankaj Singh

ur 응답 Pankaj 주셔서 감사합니다. 나는 같은 날 자체에서이 문제 sove했다
Sachin Gurnani

1
이것은 asynctask에서 수행되어야합니까? 아니면 메인 스레드에서이 작업을 수행해도 괜찮습니까?
n3wb

28

나는 빠른 해결책이 있습니다. 파일 만들기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);

13

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 을 사용해야 하지만 두 스트림이 항상 필요하므로 조금 더 복잡합니다. 다른 스레드에 있음).


2
여기서 인코딩이란 무엇입니까?
Animesh Mangla 2015

5

이것을 시도하고 먼저 이미지를 필요한 너비와 높이로 조정하고 원본 비트 맵, 필요한 너비 및 필요한 높이를 다음 메서드에 전달하고 배율이 조정 된 비트 맵을 가져옵니다.

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

3

이러한 모든 답변은 불필요하게 비트 맵으로 디코딩 한 다음 비트 맵을 다시 압축하므로 비효율적입니다. 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()
            }
        }
    }
}

보너스로 재 압축을 건너 뛰기 때문에 이미지 품질이 약간 향상되어야합니다.


1

이제 대부분의 사람들이 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)
    }

-2

이 코드를 사용하십시오 ..

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);
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.