2013-07-04 3 views
0

사진을 찍어 그 위에 오버레이를 추가하려고합니다. 여기에 내 코드 (단지 콜백)입니다 : 내 삼성 갤럭시 S3에 다음과 같은 오류가Android OutOfMemoryException 카메라로 사진 찍기

private PictureCallback mPicture = new PictureCallback() { 
     @Override 
     public void onPictureTaken(final byte[] data, Camera camera) { 


      if(!dirFile.exists()){ 
       dirFile.mkdirs(); 
      } 

      try { 
       String name = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date()) + ".jpg"; 
       picturePath = new File(dirFile, name); 

       new AsyncTask<Void, Void, Void>(){ 
        FileOutputStream fos = new FileOutputStream(picturePath); 
        Bitmap photo; 

        @Override 
        protected Void doInBackground(Void... params) { 
         photo = BitmapFactory.decodeByteArray(data, 0, data.length).copy(Config.ARGB_8888, true); 
         Bitmap cadre = BitmapFactory.decodeResource(getResources(), R.drawable.cadre16001200); 
         Canvas canvas = new Canvas(photo); 
         canvas.drawBitmap(cadre, new Matrix(), null); 
         cadre.recycle(); 

         photo.compress(CompressFormat.JPEG, 100, fos); 
         try { 
          fos.close(); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
         geotag(picturePath.toString()); 
         return null; 
        } 

        protected void onPostExecute(Void result) { 

         dialog.dismiss(); 

         mCamera.startPreview(); 


         //Affiche la nouvelle photo 
         picture.setImageBitmap(photo); 
        }; 

       }.execute(); 


      } catch (FileNotFoundException e) { 
       Log.d("PhotoActivity", "File not found: " + e.getMessage()); 
      } 

     } 
    }; 

(4.1.2 안드로이드),에서 OutOfMemoryException으로

07-04 10:01:24.076: E/dalvikvm-heap(2980): Out of memory on a 7680016-byte allocation. 

이상한 점은 작동한다는 것입니다 1600x1200 해상도의 삼성 Gio (android 2.2.1)에 완벽하게 탑재되었습니다.

내가 많이 봤 거든, 나는 그림을 다운 사이징의 주요 솔루션을 사용할 수 없습니다. 그것은 메모리 문제이지만, 어떻게 메모리 사용량을 줄일 수 있는지 모르겠습니다.

편집 : 나는이 발견, 그것은 진짜 문제라고 보인다는 UI에 proccessing 전에 비트 맵을 디코딩한다 https://stackoverflow.com/a/12377158/1343969

+1

이 실제로 필요한 'copy()'호출입니까? 그건 그냥 메모리 발자국을 두 배로해야합니다 ... – WarrenFaith

+0

어쩌면이 도움이 될 수 있습니다 : http://stackoverflow.com/a/15380872/876603 – dors

+0

@WarrenFaith 네, firstBitmap 불변이므로, 그 위에 그릴 수 없습니다. – Oyashiro

답변

0

당신은해야 코드 예제 Canvas의 빈 생성자를 호출하고 photo을 그립니다. 그러면 copy() 호출이 제거되고 메모리 사용량이 줄어 듭니다.

photo = BitmapFactory.decodeByteArray(data, 0, data.length); 
Bitmap cadre = BitmapFactory.decodeResource(getResources(), R.drawable.cadre16001200); 
Canvas canvas = new Canvas(); 
canvas.drawBitmap(photo, 0, 0, null); 
canvas.drawBitmap(cadre, new Matrix(), null); 
cadre.recycle(); 

photo.compress(CompressFormat.JPEG, 100, fos); 
+0

좋은 생각처럼 보이지만 여전히 문제를 해결하지 못합니다. decodeByteArray에 OutOfMemoryException이 있습니다. – Oyashiro

+0

그러면 소스가 아닌 증상 만 볼 수 있습니다. 너 지금 뭐하고 있니? 사진을 찍기 전에 기억을 풀어 볼 수 있습니까? – WarrenFaith

+0

takePicture() 메서드를 호출하는 단추가 하나뿐입니다. 내보기, 카메라 및 카메라 미리보기를 저장할 수있는 속성이 있지만 그 밖의 것은 없습니다. – Oyashiro

1

, 여기

private Bitmap decodeFile(File f){ 
     try { 
      //decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 
      FileInputStream stream1=new FileInputStream(f); 
      BitmapFactory.decodeStream(stream1,null,o); 
      stream1.close(); 

      //Find the correct scale value. It should be the power of 2. 
      final int REQUIRED_SIZE=70; 
      int width_tmp=o.outWidth, height_tmp=o.outHeight; 
      int scale=1; 
      while(true){ 
       if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
        break; 
       width_tmp/=2; 
       height_tmp/=2; 
       scale*=2; 
      } 

      //decode with inSampleSize 
      BitmapFactory.Options o2 = new BitmapFactory.Options(); 
      o2.inSampleSize=scale; 
      FileInputStream stream2=new FileInputStream(f); 
      Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2); 
      stream2.close(); 
      return bitmap; 
     } catch (FileNotFoundException e) { 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
} 
관련 문제