java - compress - byte to android bitmap
conversión de Java bitmap a byte array (9)
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[]
Cuando miro el búfer después de la llamada a copyPixelsToBuffer
los bytes son todos 0 ... El mapa de bits devuelto desde la cámara es inmutable ... pero eso no debería importar ya que está haciendo una copia.
¿Qué podría estar mal con este código?
¿Necesitas rebobinar el búfer, quizás?
Además, esto podría suceder si la zancada (en bytes) del mapa de bits es mayor que la longitud de la fila en píxeles * bytes / píxel. Haz la longitud de los bytes b.remaining () en lugar del tamaño.
Aquí está la extensión de mapa de bits que escribió .convertToByteArray
en Kotlin.
/**
* 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
}
CompressFormat es demasiado lento ...
Pruebe ByteBuffer.
※※※ Bitmap a byte ※※※
width = bitmap.getWidth();
height = bitmap.getHeight();
int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(byteBuffer);
byteArray = byteBuffer.array();
※※※ byte a bitmap ※※※
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);
Intenta algo como esto:
Bitmap bmp = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bmp.recycle();
Para evitar el error OutOfMemory
para archivos más grandes, resolvería la tarea dividiendo un mapa de bits en varias partes y combinando los bytes de sus partes.
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();
}
Su matriz de bytes es demasiado pequeña. Cada píxel ocupa 4 bytes, no solo 1, así que multiplique su tamaño * 4 para que la matriz sea lo suficientemente grande.
Ted Hopp es correcto, de la documentación de la API:
public void copyPixelsToBuffer (Buffer dst)
"... Después de que este método vuelve, la posición actual del búfer se actualiza: la posición se incrementa por el número de elementos escritos en el búfer".
y
public ByteBuffer get (byte[] dst, int dstOffset, int byteCount)
"Lee los bytes de la posición actual en la matriz de bytes especificada, comenzando en el desplazamiento especificado, y aumenta la posición en el número de bytes leídos".
Utilice las siguientes funciones para codificar el mapa de bits en byte [] y viceversa
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);
}
Intenta esto para convertir String-Bitmap o Bitmap-String
/**
* @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;
}
}