java - imagen - imageview to base64 android
OutOfMemoryError durante la decodificación y codificación de la Cadena Base64 en Bitmap (7)
Estoy intentando decode
y encode
una imagen de Bitmap
. En algunos dispositivos funciona perfectamente, mientras que en otros no. Estoy cargando Base64 String
en el servidor y obteniendo Base64 String
del servidor. He encontrado varias soluciones pero todavía no puedo resolver mi problema. Aquí está mi código:
Codificación:
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
getActivity().startActivityForResult(i, RESULT_LOAD_IMAGE);
}
});
//Image loading from Gallery
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK
&& null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
imageView1.setImageBitmap(BitmapFactory.decodeFile(picturePath));
if (picturePath != null && !TextUtils.isEmpty(picturePath)) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(picturePath, options);
base64ImageSend = ImageBase64.encodeTobase64(bitmap);
Log.i("Base 64 Image", base64ImageSend);
} else {
base64ImageSend = "";
}
}
}
Descodificación:
private String base64StringReceive = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCADhAOEDASIA AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+/iii igAooooAKKKKACiiigAooriPH/xB8GfC7wd4i+IPj3XbHw54T8J6e+p+INe1BilnYaerFWkdgc8n HTOARkEbyAC9qus6T4e0vVNe13UrHRdE020N7qWo392lhY2NpEW828v9RldFjVQNo3MFA6sSAx/F P9pL/gsz8O/CI1Lw/wDs0aHb/E7XrAx2f/Cf+K59T0v4YpJudt2l6bBKviLxqxICPGkvhq1ICkeM sGQt+WH7a/7fXxU/a91y+8OWR1Dwl8FNNvr5fD3gKxvPm8Q7dSYaX4k+IZyza3rRwP8AinXLeD/C Axud2J8cH4A9STg9uM4wW3dDzkbTz06DnNfk2e8eK7y/h+zklZT12UpXtq7JJ7PpZNSuz9I4f4D5 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 ";
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Bitmap bitmap = ImageBase64.decodeBase64(base64StringReceive,MainActivity.this);
imageView2.setImageBitmap(bitmap);
}
});
ImageBase64.java:
import java.io.ByteArrayOutputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import android.util.Log;
public static String encodeTobase64(Bitmap image) {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,100, baos);
byte [] b=baos.toByteArray();
String temp=null;
try{
System.gc();
temp=Base64.encodeToString(b, Base64.DEFAULT);
}catch(Exception e){
e.printStackTrace();
}catch(OutOfMemoryError e){
baos=new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,50, baos);
b=baos.toByteArray();
temp=Base64.encodeToString(b, Base64.DEFAULT);
Log.e("EWN", "Out of memory error catched");
}
return temp;
}
public static Bitmap decodeBase64(String input,Context context) {
byte[] decodedByte = Base64.decode(input, 0);
Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
File sdCardDirectory;
if (isSDPresent) {
// yes SD-card is present
sdCardDirectory = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"myFile");
if (!sdCardDirectory.exists()) {
if (!sdCardDirectory.mkdirs()) {
Log.d("MySnaps", "failed to create directory");
}
}
} else {
// Sorry
sdCardDirectory = new File(context.getCacheDir(),"");
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((1000 - 0) + 1) + 0;
String nw = "IMG_" + timeStamp + randomNum+".jpg";// also tried .txt as file extension
File image = new File(sdCardDirectory, nw);
// Encode the file as a PNG image.
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
outStream.write(input.getBytes());
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("Compress bitmap path", image.getPath());
return decodeFile(image); // BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
private static Bitmap decodeFile(File f){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_SIZE=70;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale>=REQUIRED_SIZE && o.outHeight/scale>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}
Pila de errores:
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:510)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:533)
at com.utility.ImageBase64.decodeBase64(ImageBase64.java:32)
at com.activity.HomeFragment.onCreateView(HomeFragment.java:138)
at android.app.Fragment.performCreateView(Fragment.java:1700)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:773)
at android.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1498)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:495)
at android.app.Activity.onBackPressed(Activity.java:2232)
at com.activity.MainActivity.onBackPressed(MainActivity.java:534)
at android.app.Activity.onKeyUp(Activity.java:2210)
at android.view.KeyEvent.dispatch(KeyEvent.java:2664)
at android.app.Activity.dispatchKeyEvent(Activity.java:2440)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1962)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3884)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3858)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3426)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3476)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3445)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3552)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3453)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3609)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3426)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3476)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3445)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3453)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3426)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3476)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3445)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3585)
at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3750)
at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2027)
at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1721)
at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1712)
at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2004)
at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:138)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:5050)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:806)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
at dalvik.system.NativeStart.main(Native Method)
También estoy recibiendo este error en algunos dispositivos:
java.lang.OutOfMemoryError: Failed to allocate a 38340876 byte allocation with 994361 free bytes and 971KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:655)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:678)
at com.myapp.utility.ImageBase64.decodeBase64(ImageBase64.java:53)
at com.myapp.activity.DetailProfileFragment.onCreateView(DetailProfileFragment.java:103)
at android.app.Fragment.performCreateView(Fragment.java:2114)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:904)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082)
at android.app.BackStackRecord.run(BackStackRecord.java:833)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:452)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5944)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1389)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1184)
Las soluciones que ya he probado son:
Al mostrar Bitmap
en ImageView
desde un archivo, primero BitmapHelper.decodeFile(picturePath, 200, 200, true)
con la ayuda de BitmapHelper.decodeFile(picturePath, 200, 200, true)
esto devolverá Bitmap
comprimido para que, al codificar este Bitmap, puedas manejar imágenes de alta resolución e imágenes de gran tamaño. hasta 100 MB de archivo.
Después de descodificar el archivo, ImageView
su ImageView
y obtenga el formato de la Cadena Base64
sobre la imagen comprimida utilizando la clase BitmapHelper
; obtener Bitmap
de Bitmap
de su ImageView
(es decir, ya ha sido comprimido) y utilizar ImageBase64.encodeTobase64(bitmap)
esto comprimirá nuevamente el archivo y hará que la excepción OutOfMemory
maneje mientras se Encoding
un Bitmap
.
Para la decoding
primero escriba su Base64String
en el archivo en la memoria de su dispositivo. Luego, lee Bytes
en fragmentos y decodifica ese ByteArray
con esto, tendrás tu mapa de bits en tu memoria. Después de escalar este mapa de bits usando el método decodeFile()
, entonces habrá comprimido Bitmap
desde Base64String
He buscado en varios blogs y publicaciones y de ellos he tomado el mejor código adecuado y los he combinado en uno para hacerlo más confiable. Pruebe el siguiente código para hacer que la encoding
y la decoding
más rápidas con la administración de meory.
Para decodificar Base64String
Bitmap bitmap = ImageBase64.decodeBase64(base64ImageStr,MainActivity.this);
imageView.setImageBitmap(bitmap);
bitmap = null;
System.gc();
Para codificar Bitmap
Pruebe esto:
imageView.setImageBitmap(BitmapHelper.decodeFile(picturePath, 200, 200, true));
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
base64ImageStr = ImageBase64.encodeTobase64(bitmap);
Pruebe este código para ImageBase64
public class ImageBase64 {
private ImageBase64() {
super();
}
private static Context appContext;
public static String encodeTobase64(Bitmap image) {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,100, baos);
byte [] b=baos.toByteArray();
String temp=null;
try{
System.gc();
temp=Base64.encodeToString(b, Base64.DEFAULT);
}catch(Exception e){
e.printStackTrace();
}catch(OutOfMemoryError e){
baos=new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,50, baos);
b=baos.toByteArray();
temp=Base64.encodeToString(b, Base64.DEFAULT);
Log.e("EWN", "Out of memory error catched");
}
return temp;
}
public static Bitmap decodeBase64(String input,Context context) {
byte[] decodedByte = Base64.decode(input, 0);
appContext = context;
Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
File sdCardDirectory;
if (isSDPresent) {
// yes SD-card is present
sdCardDirectory = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"IMG");
if (!sdCardDirectory.exists()) {
if (!sdCardDirectory.mkdirs()) {
Log.d("MySnaps", "failed to create directory");
}
}
} else {
// Sorry
sdCardDirectory = new File(context.getCacheDir(),"");
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((1000 - 0) + 1) + 0;
String nw = "IMG_" + timeStamp + randomNum+".txt";
File image = new File(sdCardDirectory, nw);
// Encode the file as a PNG image.
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
outStream.write(input.getBytes());
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("Compress bitmap path", image.getPath());
Bitmap bitmap;
try{
bitmap = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}catch(OutOfMemoryError e){
e.printStackTrace();
InputStream is = context.getResources().openRawResource(R.drawable.default_profile_pic);
bitmap = BitmapFactory.decodeStream(is);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
bitmap=null;
}
return bitmap;//BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
//return decodeFile(image);
}
private static Bitmap decodeFile(File f){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_SIZE=70;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale>=REQUIRED_SIZE && o.outHeight/scale>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
File sdCardDirectory;
if (isSDPresent) {
// yes SD-card is present
sdCardDirectory = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"IMG");
if (!sdCardDirectory.exists()) {
if (!sdCardDirectory.mkdirs()) {
Log.d("MySnaps", "failed to create directory");
}
}
} else {
// Sorry
sdCardDirectory = new File(appContext.getCacheDir(),"");
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((1000 - 0) + 1) + 0;
String nw = "IMG_" + timeStamp + randomNum+".png";
File image = new File(sdCardDirectory, nw);
FileOutputStream out = null;
try {
out = new FileOutputStream(image);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
String pathNew =compressImage(image.getAbsolutePath());
Uri uri = Uri.parse(pathNew);
Bitmap bitmap=null ;
try {
bitmap = MediaStore.Images.Media.getBitmap(appContext.getContentResolver(),uri);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;
} catch (FileNotFoundException e) {}
return null;
}
public static String compressImage(String imageUri) {
String filePath = imageUri;//getRealPathFromURI(imageUri);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
// max Height and width values of the compressed image is taken as 816x612
float maxHeight = 816.0f;
float maxWidth = 612.0f;
float imgRatio = actualWidth / actualHeight;
float maxRatio = maxWidth / maxHeight;
// width and height values are set maintaining the aspect ratio of the image
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) { imgRatio = maxHeight / actualHeight; actualWidth = (int) (imgRatio * actualWidth); actualHeight = (int) maxHeight; } else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
// setting inSampleSize value allows to load a scaled down version of the original image
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(filePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
// check the rotation of the image and display it properly
ExifInterface exif;
try {
exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 0);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
true);
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out = null;
String filename = getFilename();
try {
out = new FileOutputStream(filename);
// write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return filename;
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } final float totalPixels = width * height; final float totalReqPixelsCap = reqWidth * reqHeight * 2; while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
return inSampleSize;
}
public static String getFilename() {
/*File file = new File(Environment.getExternalStorageDirectory().getPath(), "IMG/Images");
if (!file.exists()) {
file.mkdirs();
}
String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
*/
Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
File sdCardDirectory;
if (isSDPresent) {
// yes SD-card is present
sdCardDirectory = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath(),
"IMG/Images");
if (!sdCardDirectory.exists()) {
if (!sdCardDirectory.mkdirs()) {
Log.d("MySnaps", "failed to create directory");
}
}
} else {
// Sorry
sdCardDirectory = new File(appContext.getCacheDir(),"");
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((1000 - 0) + 1) + 0;
String nw = "img_" + timeStamp + randomNum+".jpg";
File image = new File(sdCardDirectory, nw);
String uriSting1 = (sdCardDirectory.getAbsolutePath() + "/" + nw);//System.currentTimeMillis() + ".jpg");
return uriSting1;
}
}
Agregue esta clase para manejar imágenes pesadas
public class BitmapHelper
{
//decodes image and scales it to reduce memory consumption
public static Bitmap decodeFile(String bitmapFile, int requiredWidth, int requiredHeight, boolean quickAndDirty)
{
try
{
//Decode image size
BitmapFactory.Options bitmapSizeOptions = new BitmapFactory.Options();
bitmapSizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapSizeOptions);
// load image using inSampleSize adapted to required image size
BitmapFactory.Options bitmapDecodeOptions = new BitmapFactory.Options();
bitmapDecodeOptions.inTempStorage = new byte[16 * 1024];
bitmapDecodeOptions.inSampleSize = computeInSampleSize(bitmapSizeOptions, requiredWidth, requiredHeight, false);
bitmapDecodeOptions.inPurgeable = true;
bitmapDecodeOptions.inDither = !quickAndDirty;
bitmapDecodeOptions.inPreferredConfig = quickAndDirty ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888;
Bitmap decodedBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapDecodeOptions);
// scale bitmap to mathc required size (and keep aspect ratio)
float srcWidth = (float) bitmapDecodeOptions.outWidth;
float srcHeight = (float) bitmapDecodeOptions.outHeight;
float dstWidth = (float) requiredWidth;
float dstHeight = (float) requiredHeight;
float srcAspectRatio = srcWidth / srcHeight;
float dstAspectRatio = dstWidth / dstHeight;
// recycleDecodedBitmap is used to know if we must recycle intermediary ''decodedBitmap''
// (DO NOT recycle it right away: wait for end of bitmap manipulation process to avoid
// java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@416ee7d8
// I do not excatly understand why, but this way it''s OK
boolean recycleDecodedBitmap = false;
Bitmap scaledBitmap = decodedBitmap;
if (srcAspectRatio < dstAspectRatio)
{
scaledBitmap = getScaledBitmap(decodedBitmap, (int) dstWidth, (int) (srcHeight * (dstWidth / srcWidth)));
// will recycle recycleDecodedBitmap
recycleDecodedBitmap = true;
}
else if (srcAspectRatio > dstAspectRatio)
{
scaledBitmap = getScaledBitmap(decodedBitmap, (int) (srcWidth * (dstHeight / srcHeight)), (int) dstHeight);
recycleDecodedBitmap = true;
}
// crop image to match required image size
int scaledBitmapWidth = scaledBitmap.getWidth();
int scaledBitmapHeight = scaledBitmap.getHeight();
Bitmap croppedBitmap = scaledBitmap;
if (scaledBitmapWidth > requiredWidth)
{
int xOffset = (scaledBitmapWidth - requiredWidth) / 2;
croppedBitmap = Bitmap.createBitmap(scaledBitmap, xOffset, 0, requiredWidth, requiredHeight);
scaledBitmap.recycle();
}
else if (scaledBitmapHeight > requiredHeight)
{
int yOffset = (scaledBitmapHeight - requiredHeight) / 2;
croppedBitmap = Bitmap.createBitmap(scaledBitmap, 0, yOffset, requiredWidth, requiredHeight);
scaledBitmap.recycle();
}
if (recycleDecodedBitmap)
{
decodedBitmap.recycle();
}
decodedBitmap = null;
scaledBitmap = null;
return croppedBitmap;
}
catch (Exception ex)
{
ex.printStackTrace();
}
return null;
}
/**
* compute powerOf2 or exact scale to be used as {@link BitmapFactory.Options#inSampleSize} value (for subSampling)
*
* @param requiredWidth
* @param requiredHeight
* @param powerOf2
* weither we want a power of 2 sclae or not
* @return
*/
public static int computeInSampleSize(BitmapFactory.Options options, int dstWidth, int dstHeight, boolean powerOf2)
{
int inSampleSize = 1;
// Raw height and width of image
final int srcHeight = options.outHeight;
final int srcWidth = options.outWidth;
if (powerOf2)
{
//Find the correct scale value. It should be the power of 2.
int tmpWidth = srcWidth, tmpHeight = srcHeight;
while (true)
{
if (tmpWidth / 2 < dstWidth || tmpHeight / 2 < dstHeight)
break;
tmpWidth /= 2;
tmpHeight /= 2;
inSampleSize *= 2;
}
}
else
{
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) srcHeight / (float) dstHeight);
final int widthRatio = Math.round((float) srcWidth / (float) dstWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable instanceof BitmapDrawable)
{
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public static Bitmap getScaledBitmap(Bitmap bitmap, int newWidth, int newHeight)
{
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
Como Greenapps sugirió, sería mejor evitar el uso de Bitmap y BitmapFactory para TRANSMITIR el archivo:
FileInputStream fis = new FileInputStream(imageFile);
byte[] byteArray = inputStreamToByteArray(fis);
String base64ImageSend = Base64.encodeToString(byteArray, Base64.NO_WRAP);
dónde:
/**
* 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();
}
En realidad, el problema de OutOfMemory, según lo declarado por Kai, se debe al hecho de que está decodificando una resolución completa y una imagen de alta calidad. La mejor manera de evitar esto es reducir la resolución de su imagen:
/**
* 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 <code><b>s<sub>k</sub></b>=2<sup>k</sup></code>, with <code>k &isin ℕ</code>, such that
* <code>min<sub>k</sub>(requestedWidth-options.outWidth×<b>s<sub>k</sub></b>)>0</code>
* <code>&&</code>
* <code>min<sub>k</sub>(requestedHeight-options.outHeight×<b>s<sub>k</sub></b>)>0</code>
* @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 <code><b>s<sub>k</sub></b></code>,
* >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;
}
Pruebe con este pseudo código: hágamelo saber si tiene alguna pregunta
Bitmap bmp = (Bitmap) data.getExtras().get("data");
img.setImageBitmap(bmp);
btnadd.requestFocus();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
encodedImageString = Base64.encodeToString(b, Base64.DEFAULT);
byte[] bytarray = Base64.decode(encodedImageString, Base64.DEFAULT);
Bitmap bmimage = BitmapFactory.decodeByteArray(bytarray, 0,
bytarray.length);
Puedes probar esto, debería resolver tu problema.
Básicamente primero guarda los datos en un archivo, usando un buffer para evitar problemas de memoria. Después de eso, verificamos y cambiamos el tamaño del archivo, cargando directamente un Bitmap redimensionado, nuevamente para evitar problemas de memoria.
Por lo que puedo suponer, está obteniendo la cadena codificada de un servidor ... por lo que puede administrar su código para escribir directamente en el archivo.
Escribir los datos en el archivo:
private Bitmap getBitmapThumbnail(String base64StringReceive) {
byte[] data = Base64.decode(base64StringReceive, Base64.DEFAULT);
File file = new File(getFilesDir(), "testFile");
try {
BufferedOutputStream bos = new BufferedOutputStream(openFileOutput("testFile", Context.MODE_PRIVATE),1024);
bos.write(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return getThumbFromFile(file, false);
}
Creando la miniatura desde el archivo de imagen:
private Bitmap getThumbFromFile(File file) {
Bitmap tempImage = null;
try {
tempImage = decodeSampledBitmapFromFile(file.getAbsolutePath(), 50, 50); // this is in pixels - use your desired size
return ThumbnailUtils.extractThumbnail(tempImage, 50, 50);
} finally {
if (tempImage != null) {
tempImage.recycle();
}
}
}
Cargando solo un mapa de bits redimensionado:
private Bitmap decodeSampledBitmapFromFile(String filePath, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
Calculando el valor de muestreo proporcionado por Google, puede encontrar sus tutoriales:
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight &&
(halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
Simplemente aumente el tamaño de almacenamiento dinámico de su aplicación en el archivo de manifiesto.
android:largeHeap="true"
eg:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppTheme"
android:largeHeap="true" >
Yo sugeriría que:
Si recibe datos de un servidor utilizando un protocolo basado en xml, use el analizador SAX en lugar de DOM.
No cargue toda la cadena base64 en la memoria. Se usa
InputStream
para cargar una porción de datos en labyte[]
matriz, decodificar Base64 de la matriz y anexar el resultado a un archivo de caché a través deFileOutputStream
.Use la opción options.inJustDecodeBounds para evitar que un archivo de mapa de bits de escala completa se cargue en la memoria. Puede evaluar la cantidad total de memoria requerida y tomar una decisión para reducirla, por ejemplo. UPD . Me di cuenta de que ya lo estás usando.
Tenga en cuenta referencias de objetos que está reteniendo y pasando a través de su flujo de métodos. Las referencias fuertes evitan que GC recupere memoria.
Siguiendo su código: el método decodeBase64
contiene un String input
parámetro de argumento en la pila, byte[] decodedByte
referencia y retorno BitmapFactory.decodeStream(new FileInputStream(f), null, o2)
al final. Mantener todos estos objetos en la memoria al mismo tiempo significa una gran presión en la asignación de GC y memoria en general. Como solución más simple puede hacer null
referencias justo después de que se hayan utilizado los objetos correspondientes (cadena y matriz de bytes), por lo que GC podrá liberarlos.
No está codificando base64 una instancia de mapa de bits (como sugiere en su publicación e incluso en el tema) sino una matriz de bytes b
enString imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
. La matriz de bytes ''b'' contiene los bytes de lo que sería el contenido de un archivo .jpg si escribes estos bytes en el archivo.
Lo que tienes que hacer es colocar los contenidos del archivo .jpg que deseas subir directamente en una matriz de bytes. Luego codifica esa matriz.
Google para android put file content in byte array
. El código ha sido publicado muchas veces en este sitio