Java 비트맵을 바이트 배열로 변환
Bitmap bmp = intent.getExtras().get("data");
int size = bmp.getRowBytes() * bmp.getHeight();
ByteBuffer b = ByteBuffer.allocate(size);
bmp.copyPixelsToBuffer(b);
byte[] bytes = new byte[size];
try {
b.get(bytes, 0, bytes.length);
} catch (BufferUnderflowException e) {
// always happens
}
// do something with byte[]
호출 후 버퍼를 보면copyPixelsToBuffer바이트는 모두 0...카메라에서 반환된 비트맵은 불변입니다...복사를 하고 있으니 그건 문제가 되지 않을 겁니다
이 코드에 어떤 문제가 있을까요?
다음과 같은 방법을 사용해 보십시오.
Bitmap bmp = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bmp.recycle();
CompressFormat이 너무 느립니다...
Byte Buffer를 사용해 보세요.
※ ※ ※ 비트맵과 바이트 ※ ※ ※
width = bitmap.getWidth();
height = bitmap.getHeight();
int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(byteBuffer);
byteArray = byteBuffer.array();
※ ※ ※ 비트맵에 바이트 ※ ※ ※
Bitmap.Config configBmp = Bitmap.Config.valueOf(bitmap.getConfig().name());
Bitmap bitmap_tmp = Bitmap.createBitmap(width, height, configBmp);
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
bitmap_tmp.copyPixelsFromBuffer(buffer);
비트맵 확장자는 다음과 같습니다..convertToByteArray코틀린어로 썼다.
/**
* Convert bitmap to byte array using ByteBuffer.
*/
fun Bitmap.convertToByteArray(): ByteArray {
//minimum number of bytes that can be used to store this bitmap's pixels
val size = this.byteCount
//allocate new instances which will hold bitmap
val buffer = ByteBuffer.allocate(size)
val bytes = ByteArray(size)
//copy the bitmap's pixels into the specified buffer
this.copyPixelsToBuffer(buffer)
//rewinds buffer (buffer position is set to zero and the mark is discarded)
buffer.rewind()
//transfer bytes from buffer into the given destination array
buffer.get(bytes)
//return bitmap's pixels
return bytes
}
버퍼를 되감아야 하나요?
또한 비트맵의 스트라이드(바이트 단위)가 행 길이(픽셀당 *바이트 수)보다 큰 경우에도 발생할 수 있습니다.크기 대신 b.remaining() 바이트 길이를 지정합니다.
다음 함수를 사용하여 비트맵을 바이트[]로 인코딩하거나 비트맵을 바이트[]로 인코딩합니다.
public static String encodeTobase64(Bitmap image) {
Bitmap immagex = image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
immagex.compress(Bitmap.CompressFormat.PNG, 90, baos);
byte[] b = baos.toByteArray();
String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
return imageEncoded;
}
public static Bitmap decodeBase64(String input) {
byte[] decodedByte = Base64.decode(input, 0);
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
바이트 배열이 너무 작습니다.각 픽셀은 1바이트뿐만 아니라 4바이트를 차지하므로 어레이가 충분히 커지도록 크기 *4를 곱합니다.
API Documentation의 Ted Hopp은 다음과 같습니다.
public void copyPixelsToBuffer (Buffer dst)
"... 이 메서드가 반환되면 버퍼의 현재 위치가 갱신됩니다.이 위치는 버퍼에 입력된 요소의 수만큼 증가합니다."
그리고.
public ByteBuffer get (byte[] dst, int dstOffset, int byteCount)
"지정한 오프셋부터 시작하여 현재 위치에서 지정된 바이트 배열로 바이트를 읽고 읽은 바이트 수만큼 위치를 늘립니다."
피하려면OutOfMemory큰 파일의 경우 비트맵을 여러 부분으로 나누고 각 부분의 바이트를 병합하여 작업을 해결하는 것이 좋습니다.
private byte[] getBitmapBytes(Bitmap bitmap)
{
int chunkNumbers = 10;
int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
byte[] imageBytes = new byte[bitmapSize];
int rows, cols;
int chunkHeight, chunkWidth;
rows = cols = (int) Math.sqrt(chunkNumbers);
chunkHeight = bitmap.getHeight() / rows;
chunkWidth = bitmap.getWidth() / cols;
int yCoord = 0;
int bitmapsSizes = 0;
for (int x = 0; x < rows; x++)
{
int xCoord = 0;
for (int y = 0; y < cols; y++)
{
Bitmap bitmapChunk = Bitmap.createBitmap(bitmap, xCoord, yCoord, chunkWidth, chunkHeight);
byte[] bitmapArray = getBytesFromBitmapChunk(bitmapChunk);
System.arraycopy(bitmapArray, 0, imageBytes, bitmapsSizes, bitmapArray.length);
bitmapsSizes = bitmapsSizes + bitmapArray.length;
xCoord += chunkWidth;
bitmapChunk.recycle();
bitmapChunk = null;
}
yCoord += chunkHeight;
}
return imageBytes;
}
private byte[] getBytesFromBitmapChunk(Bitmap bitmap)
{
int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(bitmapSize);
bitmap.copyPixelsToBuffer(byteBuffer);
byteBuffer.rewind();
return byteBuffer.array();
}
이거면 될 것 같은데...
public static byte[] convertBitmapToByteArray(Bitmap bitmap){
ByteBuffer byteBuffer = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(byteBuffer);
byteBuffer.rewind();
return byteBuffer.array();
}
문자열 비트맵 또는 비트맵 문자열을 변환하려면 이 작업을 수행하십시오.
/**
* @param bitmap
* @return converting bitmap and return a string
*/
public static String BitMapToString(Bitmap bitmap){
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
byte [] b=baos.toByteArray();
String temp=Base64.encodeToString(b, Base64.DEFAULT);
return temp;
}
/**
* @param encodedString
* @return bitmap (from given string)
*/
public static Bitmap StringToBitMap(String encodedString){
try{
byte [] encodeByte=Base64.decode(encodedString,Base64.DEFAULT);
Bitmap bitmap= BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
return bitmap;
}catch(Exception e){
e.getMessage();
return null;
}
}
언급URL : https://stackoverflow.com/questions/4989182/converting-java-bitmap-to-byte-array
'source' 카테고리의 다른 글
| Java 순서 맵 (0) | 2022.08.11 |
|---|---|
| Java의 SimpleDateFormat이 스레드 세이프가 아닌 이유는 무엇입니까? (0) | 2022.08.11 |
| Store vuex가 정의되지 않은 속성 'store'를 읽을 수 없습니다." (0) | 2022.08.10 |
| libcurl 없이 C에서 HTTP get 요구를 작성하려면 어떻게 해야 합니까? (0) | 2022.08.10 |
| C에 화살표(->) 연산자가 존재하는 이유는 무엇입니까? (0) | 2022.08.10 |