2013-05-24 2 views
3

비트 맵을 찍고 원본에서 새 비트 맵을 만든 다음 새 비트 맵을 ImageView으로 설정합니다. 원본을 재활용하면 원래대로 그려지는 것은 아닙니다. 자세한 내용은 내 코드에서 내 의견을 읽으십시오. 당신이 볼 수 있듯이 내가 그리지 않는 비트 맵을 재활용합니다. 항상 타일이라는 새로운 비트 맵을 만듭니다.왜 "재활용 비트 맵을 그릴 수 없습니까?"

내 코드 :

public void tileImage(Bitmap bm){ 
    if(bm==null){ 
     Debug.out("Bitmap is null"); 
    } 
    else{ 
     Bitmap tile; 
     float tileWidth = bm.getWidth(); 
     float tileHeight =1024; 
//if my bitmap is too wide 
     if(bm.getWidth()>width){ 
      Debug.out("Bitmap too wide: "+bm.getWidth()); 
//if this code runs I get no error, if not I get the error 
      bm = Bitmap.createScaledBitmap(bm, 
       (int)width, 
       (int)(bm.getHeight()*(float)(width/tileWidth)), 
       false 
       ); 
      } 
     Debug.out("Bitmap height: "+bm.getHeight()+" adjusted width "+bm.getWidth()); 
//if my bitmap is too tall 
     if(bm.getHeight()>tileHeight){ 
       for(int i = 0; tileHeight*i<bm.getHeight(); i++){ 
        image = new ImageView(main); 
//make tiles of the body 
        if((tileHeight*(i+1))<bm.getHeight()){ 
         tile = Bitmap.createBitmap(
           bm, 
           0, 
           (int)(tileHeight*i), 
           (int)bm.getWidth(), 
           (int)(tileHeight) 
          ); 
          Debug.out("Tiling: "+i); 
         } 
//tile the reaminder 
        else{ 
          tile = Bitmap.createBitmap(
           bm, 
           0, 
           (int)(tileHeight*i), 
           (int)bm.getWidth(), 
           (int)(bm.getHeight()%tileHeight) 
         ); 
          Debug.out("Tiling: "+bm.getHeight()%tileHeight+" "+i); 
        } 
       image.setImageBitmap(tile); 
       tiles.addView(image);    
      } 
     } 
//else its not too tall 
    else{ 
     image = new ImageView(main); 

     Debug.out("No tiling"); 

     tile = Bitmap.createBitmap(
       bm, 
       0, 
       0, 
       (int)bm.getWidth(), 
       (int)bm.getHeight() 
       ); 
     Debug.out("Bitmap too small height: "+bm.getHeight()+" width "+bm.getWidth()); 
      image.setImageBitmap(tile); 
     tiles.addView(image); 

    } 

    } 
//this is the trouble maker 
bm.recycle(); 
} 
+0

http://developer.android.com/training/displaying-bitmaps/manage-memory.html 참조하면 titleimage 방법의 호출 후에 비트 맵을 사용한 적이 – stinepike

+0

없는 당신은 – Osman

+0

입니다 ..하지만 경우에 표시되는 내용 비트 맵이 너무 넓을 때처럼 var을 재 할당하면 단서를 줘야합니다. 왜냐하면 블록이 오류를 발생시키지 않는 비트 맵에서 ... 동일한 비트 맵과 모든 것을 발생시키기 때문입니다. – stinepike

답변

3
  • Bitmap.createBitmap은 (PARAMS) 원본 비트 맵의 ​​특정 부분 집합에서 불변의 비트 맵을 돌려줍니다. 새 비트 맵은 소스와 동일한 객체이거나 사본이 작성되었을 수 있습니다.

  • bitmap.recycle() 메서드이 비트 맵과 연결된 네이티브 개체를 해제하고 픽셀 데이터에 대한 참조를 지 웁니다. 이것은 고급 호출이며 일반적으로 호출 할 필요가 없습니다. 일반적인 GC 프로세스는이 비트 맵에 대한 참조가 더 이상 없을 때이 메모리를 비 웁니다.

  • onDraw() 메서드를 사용하면보기가 팽창하는데 다소 시간이 걸립니다. 비트 맵을 전달하여 뷰를 그리는 경우 동일한 참조에서 recycle()을 호출하면 비트 맵은 "dead"로 표시됩니다. 즉, getPixels() 또는 setPixels()가 호출되면 예외를 throw하고 아무 것도 그리지 않습니다 .

  • onDestroy()에서 recycle()을 호출해야합니다.

내 코드 :

public class MainActivity extends Activity { 
    private Bitmap mBitmap; 

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

     ImageView image1 = (ImageView) findViewById(R.id.image1); 
     mBitmap = BitmapFactory.decodeResource(getResources(), 
      R.drawable.ic_launcher); 
     image1.setImageBitmap(mBitmap); 
     tileImage(); 
    } 

    private void tileImage() { 
     ImageView image2 = (ImageView) findViewById(R.id.image2); 
     Bitmap bm = Bitmap.createBitmap(mBitmap, 0, 0, 
      (int) mBitmap.getWidth(), (int) mBitmap.getHeight()); 
     image2.setImageBitmap(bm); 
    } 

    @Override 
    protected void onDestroy() { 
     mBitmap.recycle(); 
     super.onDestroy(); 
    } 
} 
+0

나는 알지 못했습니다. 그것은 같은 비트 맵을 반환 할 수 있습니다. 그것은 내 문제가 될 것 같아요. 나는 종종 오래된 것과 같은 높이와 너비의 새로운 비트 맵을 만들려고 노력합니다 .... 나는 오래된 것을 재활용 할 수 있도록 이렇게합니다. – Osman

+0

mBitmap.recycle()은 고급 호출이며 일반적으로 호출 할 필요가 없습니다. 일반적인 GC 프로세스는이 비트 맵에 대한 참조가 더 이상 없을 때이 메모리를 비 웁니다. –

+0

고급 통화가 아닙니다. 더 이상 비트 맵이 필요 없으면, 리사이클을 호출해야합니다. 단순한. 실제로 공식 문서에서는 GC가 작동하는 방식 때문에 API 수준 <11에 대한 재활용 호출을 사용하는 것이 좋습니다. onDestroy를 기다리기 전에 recycle을 호출하면 OOM 오류를 방지 할 수 있습니다. http://developer.android.com/training/displaying-bitmaps/manage-memory.html을 참조하십시오. –

0

위의 대답은 완전히 정확하지 않습니다. 사실 onDestroy가 재활용 될 때까지 기다리지 말아야합니다. 특히 이러한 비트 맵을 많이 만드는 경우. OOM 오류가 발생하기 전에 onDestroy에 도달하지 못할 수도 있습니다. 당신이해야 할 일은 비트 맵의 ​​차원에 맞게 크기를 조정하는 차원을 테스트하는 것입니다. 두 비트가 같으면 원래 비트 맵을 반환하고 재활용 할 필요가 없습니다. 그렇지 않으면 새 비트 맵 객체가 생기고 즉시 원래 비트 맵에서 recyle을 호출해야합니다.

관련 문제