首页 文章

将Base64字符串解码并编码为Bitmap时出现OutOfMemoryError

提问于
浏览
37

我正在尝试 decodeencode 一个 Bitmap 图像 . 在某些设备上它运行完美,而在其他设备上它's not. I' m上传 Base64 String 到服务器并从服务器获取 Base64 String . 我've found various solutions but still am not able to solve my issue. Here'是我的代码:

Encoding:

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 = "";
            }

        }
}

Decoding:

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;
}

Error Stack:

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)

我也在某些设备中收到此错误:

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)

我已经尝试过的解决方案是:

7 回答

  • 13

    当从文件中显示 ImageView ImageView 时,首先在 BitmapHelper.decodeFile(picturePath, 200, 200, true) 的帮助下解码它,这将返回压缩的 Bitmap ,这样在编码此Bitmap时,您可以处理高分辨率图像以及高达100 MB文件的大尺寸图像 .

    解码文件后,将其设置为 ImageView ,并使用 BitmapHelper class获取压缩图像上方的 Base64 字符串形式;从 ImageView 获取 Bitmap (即已经被压缩)并使用 ImageBase64.encodeTobase64(bitmap) 这将再次压缩文件并在 Encoding a Bitmap 时处理 OutOfMemory 异常 .

    对于 decoding ,首先将 Base64String 写入设备内存中的文件 . 然后读取块中的 Bytes 并解码 ByteArray ,这将使您的位图在您的内存中 . 在使用 decodeFile() 方法缩小此位图之后,您将从 Base64String 压缩 Bitmap

    我搜索了各种各样的博客并发布了帖子,并从中发布了我最合适的代码并将它们组合成一个以使其更可靠 . 尝试下面的代码,使用meory管理更快地 encodingdecoding .

    解码 Base64String

    Bitmap bitmap = ImageBase64.decodeBase64(base64ImageStr,MainActivity.this);
    imageView.setImageBitmap(bitmap);
    bitmap = null;
    System.gc();
    

    编码 Bitmap 试试这个:

    imageView.setImageBitmap(BitmapHelper.decodeFile(picturePath, 200, 200, true));
    
    Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();              
    base64ImageStr = ImageBase64.encodeTobase64(bitmap);
    

    试试这个代码 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;
    
        }
    }
    

    添加此类以处理繁重的图像

    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;
        }
    
    }
    
  • 5

    我建议你:

    • 如果使用基于xml的协议从服务器接收数据 - 请使用 SAX parser而不是DOM .

    • 不要将整个base64字符串加载到内存中 . 使用 InputStream 将部分数据加载到 byte[] 数组中,从数组中解码Base64并通过 FileOutputStream 将结果附加到缓存文件 .

    • 使用options.inJustDecodeBounds选项可防止将满量程位图文件加载到内存中 . 例如,您可以评估所需的内存总量,并决定将其缩小 . UPD . 我注意到你已经在使用它了 .

    • 请记住您持有的对象引用并通过方法流程 . 强引用可防止GC回收内存 .

    在您的代码之后:方法 decodeBase64 在堆栈中保存 String input 参数参数, byte[] decodedByte 参考并在最后返回 BitmapFactory.decodeStream(new FileInputStream(f), null, o2) . 同时将所有这些对象保存在内存中意味着GC和内存分配的压力很大 . 作为最简单的解决方案,您可以在使用相应的对象(字符串和字节数组)之后进行引用,因此GC将能够释放它们 .

  • 6

    试试这个伪代码:如果您有任何疑问,请告诉我

    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);
    
  • 17

    只需在清单文件中增加应用程序的堆大小即可 .

    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" >
    
  • 5

    您不是base64编码Bitmap实例(正如您在帖子中甚至在主题中所建议的那样),而是 String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT); 中的字节数组 b . 如果要将这些字节写入文件,则字节数组'b'包含.jpg文件内容的字节 .

    您需要做的是将要上载的.jpg文件的内容直接放在字节数组中 . 然后编码该数组 .

    谷歌 android put file content in byte array . 代码已在本网站上多次发布

  • 6

    正如greenapps建议的那样,最好避免使用Bitmap和BitmapFactory来传输文件:

    FileInputStream fis = new FileInputStream(imageFile);
    byte[] byteArray = inputStreamToByteArray(fis);
    String base64ImageSend = Base64.encodeToString(byteArray, Base64.NO_WRAP);
    

    哪里:

    /**
     * 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();
    }
    

    实际上,如Kai所述,outOfMemory问题是由于您正在解码全分辨率和高质量图像 . 避免这种情况的更好方法是对您的图像进行下采样:

    /**
     * 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 &#8469;</code>, such that
     * <code>min<sub>k</sub>(requestedWidth-options.outWidth&times;<b>s<sub>k</sub></b>)&gt;0</code>
     * <code>&&</code>
     * <code>min<sub>k</sub>(requestedHeight-options.outHeight&times;<b>s<sub>k</sub></b>)&gt;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>,
     * &gt;1 if the image needs to be down-sampled,
     * &lt;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;
    }
    
  • 2

    你可以尝试这个,它应该解决你的问题 .

    基本上首先将数据保存到文件中,使用缓冲区来避免内存问题 . 之后我们检查并调整文件大小 - 直接加载调整大小的位图,再次避免内存问题 .

    从我可以想到的,你从服务器获取编码的字符串...所以你可以管理你的代码直接写入文件 .

    将数据写入文件:

    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);
        }
    

    从图像文件创建缩略图:

    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();
            }
        }
    }
    

    仅加载已调整大小的位图:

    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);
    }
    

    计算采样值 - 由Google提供,您可以找到他们的教程:

    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;
    }
    

相关问题