마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

이미지 회전 처리시 메모리 부족 현상에 관한 질문.

0 추천

앨범으로부터 사진을 한 장 가져와 화면에 뿌려주려 합니다.

그냥 그대로 가져와서 뿌리게 되면 항상 90도 회전된 이미지가 보여지더라구요.

그래서 구글링을 통해 이미지 회전 함수를 적용했는데 계속해서 메모리아웃익셉션에 걸려 원본을 리턴합니다.

이 작업이 메모리를 그렇게 많이 잡아먹는 작업인가요? 아니면 제 기기의 메모리가 작은걸까요..

갤럭시 S2에서 작업하고 있습니다..

 

아래는 소스코드 전문입니다.

package com.choeunsung.example.cameratest;

import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button btn = null;
    ImageView iv = null;
    int REQUEST_IMAGE = 002;
    Bitmap m_img = null;

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setup();
    }

    private void setup(){
        btn = (Button)findViewById(R.id.btn);
        iv = (ImageView)findViewById(R.id.iv);

        btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQUEST_IMAGE);
            }
        });

        return;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        final Uri selectImageUri = data.getData();
        final String[] filePathColumn = {MediaStore.Images.Media.DATA};
        final Cursor imageCursor = this.getContentResolver().query(selectImageUri, filePathColumn, null, null, null);
        imageCursor.moveToFirst();
        final int columnIndex = imageCursor.getColumnIndex(filePathColumn[0]);
        final String imagePath = imageCursor.getString(columnIndex);
        imageCursor.close();

        m_img = BitmapFactory.decodeFile(imagePath);

        try{
            ExifInterface exif = new ExifInterface(imagePath);
            int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            int exifDegree = exifOrientationToDegrees(exifOrientation);
            m_img = rotate(m_img, exifDegree);

            iv.setImageBitmap(m_img);
        } catch (Exception e){
            Toast.makeText(this, "오류발생: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
    }
    }

    public int exifOrientationToDegrees(int exifOrientation)
    {
        if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_90)
        {
            return 90;
        }
        else if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_180)
        {
            return 180;
        }
        else if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_270)
        {
            return 270;
        }
        return 0;
    }

    public Bitmap rotate(Bitmap bitmap, int degrees)
    {
        if(degrees != 0 && bitmap != null)
        {
            Matrix m = new Matrix();
            m.setRotate(degrees, (float) bitmap.getWidth() / 2,
                    (float) bitmap.getHeight() / 2);

            try
            {
                Bitmap converted = Bitmap.createBitmap(bitmap, 0, 0,
                        bitmap.getWidth(), bitmap.getHeight(), m, true);
                if(bitmap != converted)
                {
                    bitmap.recycle();
                    bitmap = converted;
                }
            }
            catch(OutOfMemoryError ex)
            {
                // 메모리가 부족하여 회전을 시키지 못할 경우 그냥 원본을 반환합니다.
                Toast.makeText(this, "원본반환", Toast.LENGTH_LONG).show();
            }
        }
        return bitmap;
    }

    public native String stringFromJNI();
}

 

조은성 (200 포인트) 님이 2016년 11월 29일 질문
갤S2라... 흐음... OS가 어떻게 되세요?
4.1 젤리빈입니다 근데 아랫분이 말씀해주신 android:largeHeap="true"로 해결됐습니다.

1개의 답변

0 추천
1. manifest application : android:largeHeap="true" 넣어보기..

2. BitmapFactory 통해서 이미지 처리..

3. Glide 같은 이미지로더 라이브러리 사용...
익명사용자 님이 2016년 11월 29일 답변
답변 감사합니다! 1번으로 다 해결됐네요
...