I\'m trying to decode and encode a Bitmap image. On some devices it runs perfectly while on others it\'s not. I\'m uploading Bas
As greenapps suggested, it would be better to avoid using Bitmap and BitmapFactory in order to TRANSMIT the file:
FileInputStream fis = new FileInputStream(imageFile);
byte[] byteArray = inputStreamToByteArray(fis);
String base64ImageSend = Base64.encodeToString(byteArray, Base64.NO_WRAP);
where:
/**
* Convert an InputStream object into a byte array
* @param inputStream The InputStream to convert
* @return The byte[] representing the converted InputStream or null if the inputStream is null
*/
public static byte[] inputStreamToByteArray(InputStream inputStream) throws IOException {
if(inputStream==null) {
return null;
}
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
Actually the outOfMemory problem, as stated by Kai, is due to the fact that you are decoding a full resolution and high quality image. The better way to avoid this is to downsampling your image:
/**
* Decode a file, representing an image, into a bitmap, trying to scale the original image if required
* @param context The application context
* @param file The image file
* @param requestedWidth The requested width
* @param requestedHeight The requested height
* @return The decoded bitmap or null if it is not possible to decode the file parameter
*/
public static Bitmap decodeImageFileIntoMutableBitmap(Context context, File file, int requestedWidth, int requestedHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; // just compute size, don't create bitmap
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
float sampleSize = computeImageScaleCoefficient(options, requestedWidth, requestedHeight);
if (sampleSize == -1) {
return null;
}
else if (sampleSize <= 1) {
options.inSampleSize = 1;
}
else {
options.inSampleSize = (int) sampleSize;
}
options.inJustDecodeBounds = false; // compute size and create bitmap
/*it is possible to reduce the memory when decoding through skipping ARGB_8888 and using RGB_565 instead and inDither to true to preserve image quality.*/
//options.inPreferredConfig = Bitmap.Config.RGB_565;
//options.inDither = true;
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
if (bitmap == null) {
return null;
}
return bitmap;
}
/**
* Find the sample coefficient sk=2k, with k &isin ℕ, such that
* mink(requestedWidth-options.outWidth×sk)>0
* &&
* mink(requestedHeight-options.outHeight×sk)>0
* @param options The BitmapFactory.Options instance of the original image user wants to scale
* @param requestedWidth The requested width
* @param requestedHeight The requested height
* @return -1 if if there is an error trying to decode the image
* or the sample coefficient sk,
* >1 if the image needs to be down-sampled,
* <1 if the image needs to be up-sampled
*/
public static float computeImageScaleCoefficient(BitmapFactory.Options options, int requestedWidth, int requestedHeight) {
float sampleCoefficient = 1;
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;
if (imageWidth == -1 || imageHeight == -1) {
return -1;
}
double outWidth = imageWidth;
double outHeight = imageHeight;
if ((outWidth > requestedWidth) || (outHeight > requestedHeight)) {
while ((outWidth > requestedWidth) || (outHeight > requestedHeight)) {
outWidth = Math.floor(outWidth/2.0);
outHeight = Math.floor(outHeight/2.0);
sampleCoefficient *= 2.0;
}
}
else {
while ((outWidth < requestedWidth) && (outHeight < requestedHeight)) {
outWidth *= 2;
outHeight *= 2;
if ((outWidth <= requestedWidth) && (outHeight <= requestedHeight)) {
sampleCoefficient /= 2.0;
}
}
}
return sampleCoefficient;
}