web-dev-qa-db-ja.com

Base64文字列をビットマップにデコードおよびエンコードする際のOutOfMemoryError

decodeencodeBitmapイメージにしようとしています。一部のデバイスでは完全に動作しますが、他のデバイスでは動作しません。 Base64 Stringをサーバーにアップロードし、サーバーからBase64 Stringを取得しています。さまざまな解決策を見つけましたが、それでも問題を解決できません。ここに私のコードがあります:

エンコーディング:

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

        }
}

デコード:

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

エラースタック:

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)

私がすでに試したソリューションは次のとおりです。

37
Nak Android Dev

ファイルのBitmapImageViewを表示する場合、最初にBitmapHelper.decodeFile(picturePath, 200, 200, true)を使用してデコードすると、圧縮されたBitmapが返されるため、このBitmapをエンコードしている間、高解像度画像と最大100 MBの重い画像を処理できます。

ファイルをデコードした後、ImageViewに設定し、BitmapHelperクラスを使用して、圧縮画像の上に_Base64_文字列形式を取得します。 BitmapからImageViewを取得し(つまり、既に圧縮されている)、ImageBase64.encodeTobase64(bitmap)を使用します。これにより、ファイルが再び圧縮され、OutOfMemoryEncodingであるときに例外Bitmapが処理されます。

decodingの場合、最初に_Base64String_をデバイスメモリのファイルに書き込みます。次に、Bytesをチャンクで読み取り、これによりByteArrayをデコードすると、ビットマップがメモリに格納されます。 decodeFile()メソッドを使用してこのビットマップを縮小すると、_Base64String_からBitmapが圧縮されます。

さまざまなブログを検索して投稿し、それらから最適なコードを取得して1つにまとめ、信頼性を高めました。以下のコードを試して、encodingおよびdecodingをmeory管理でさらに高速化してください。

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

}
_
17

次のことをお勧めします。

  1. Xmlベースのプロトコルを使用してサーバーからデータを受信する場合-DOMの代わりに[〜#〜] sax [〜#〜]パーサーを使用します。

  2. Base64文字列全体をメモリにロードしないでください。 InputStreamを使用して、データの一部を_byte[]_配列にロードし、配列からBase64をデコードし、FileOutputStreamを介してキャッシュファイルに結果を追加します。

  3. options.inJustDecodeBounds オプションを使用して、メモリへのフルスケールビットマップファイルのロードを防止します。たとえば、必要なメモリの合計量を評価し、それを縮小する決定を下すことができます。 [〜#〜] upd [〜#〜]。すでに使用していることに気付きました。

  4. 保持し、メソッドフローを通じて渡すオブジェクト参照に留意してください。強い参照は、GCによるメモリの再利用を防ぎます。

コードに続いて:メソッド_decodeBase64_はスタックに_String input_引数パラメーターを保持し、_byte[] decodedByte_ referenceを保持し、最後にBitmapFactory.decodeStream(new FileInputStream(f), null, o2)を返します。これらすべてのオブジェクトを同時にメモリに保持することは、一般的にGCとメモリの割り当てに大きな圧力がかかることを意味します。最も簡単な解決策として、対応するオブジェクト(文字列およびバイト配列)が使用された直後にnull参照することができるため、GCはそれらを解放できます。

13
Johnny Doe

この擬似コードで試してください:質問がある場合はお知らせください

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);
6
NikW

マニフェストファイルでアプリケーションのヒープサイズを増やすだけです。

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" >
6
Shahbaz Akhtar

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

あなたは、あなたの投稿や件名でも提案しているように、Bitmapインスタンスをbase64でエンコードしているのではなく、String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);のバイト配列bをエンコードしています。バイト配列 'b'には、これらのバイトをファイルに書き込む場合の.jpgファイルの内容のバイトが含まれます。

あなたがしなければならないのは、バイト配列に直接アップロードしたい.jpgファイルの内容を入れることです。次に、その配列をエンコードします。

Google for Android put file content in byte array。このサイトには何度もコードが投稿されています

5
greenapps

これを試すことができます、それはあなたの問題を解決するはずです。

基本的に、メモリの問題を避けるためにバッファを使用して、最初にデータをファイルに保存します。その後、ファイルの確認とサイズ変更を行います。メモリの問題を回避するために、サイズ変更されたビットマップを直接ロードします。

私が推測できることから、サーバーからエンコードされた文字列を取得しています...ので、コードを管理してファイルに直接書き込むことができます。

データをファイルに書き込む:

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