2012-02-14 43 views
4

我想弄清楚怎麼用帆布畫一個小圖形(並不重要,它是什麼)到大的白色表面。問題是,如果我從一個大的空位圖開始,當我使用ARGB_8888製作它的可變副本時,Android立即耗盡內存。我很好奇,如果我失去了一些東西,或者如果它實際上不可能複合材料的小圖形到一個大的白色表面和出保存爲PNG或JPG由於Android的內存限制。如何用Canvas創建一個巨大的白色位圖?

+0

有多大是 「大」? – 2012-02-14 15:33:12

+0

與您提供的信息,那麼最簡單的優化是不使用ARGB_8888,只是使用RGB_888,因爲它聽起來像你的形象是一個不透明的塗料。這樣可以爲您的圖像每像素節省一個字節。也許你可以提供你用來繪製圖像的代碼,然後我們可以幫助你更好地回答你的問題? – 2012-02-14 16:30:34

+0

它是一種不透明的塗料,但這不是我的問題。我的願望是將我的畫布內容轉儲到新的位圖上,而不是重複使用前一個。有沒有辦法將畫布寫入字節數組?或者我註定要始終使用預先存在的位圖來繪製? – 2012-02-14 18:02:54

回答

6

當然,你是受內存限制,當你想創造巨大的位圖,但你有足夠的內存來創建相當大的位圖。例如,1024 * 1024 ARGB_8888位圖將需要大約400 MB的內存,如果你的應用程序是節儉與一般的內存是沒有問題的。 Android應用程序的正常堆大小通常在16-32 MB之間,具體取決於Android版本,只是爲了讓您感受一下您必須玩的東西。

你說你讓大位圖的副本,這可能是你的主要問題。沒有必要製作一個大的位圖副本,你只需要一個。下面是一個創建一個大的(1024 * 1024)的白色位圖,並在它的中間畫在你的應用程序視圖的樣本項目,然後將結果寫入PNG:

package com.example.android; 

import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import android.view.View; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 

public class WhitePngActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     findViewById(R.id.draw_to_bitmap).setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 
       Bitmap largeWhiteBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888); 

       // Make a canvas with which we can draw to the bitmap 
       Canvas canvas = new Canvas(largeWhiteBitmap); 

       // Fill with white 
       canvas.drawColor(0xffffffff); 

       // Draw the view to the middle of the big white bitmap. In this 
       // case, it will be the button, but you can draw any View in 
       // your view hierarchy to the bitmap like this. And of course 
       // you can position the View anywhere you want 
       canvas.save(); 
       canvas.translate(
         largeWhiteBitmap.getWidth()/2 - view.getWidth()/2, 
         largeWhiteBitmap.getHeight()/2 - view.getHeight()/2); 
       view.draw(canvas); 
       canvas.restore(); 

       // Write the file (don't forget android.permission.WRITE_EXTERNAL_STORAGE) 
       File pictureDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 
       File pngFile = new File(pictureDir, "big-white-image-with-view.png"); 
       try { 
        largeWhiteBitmap.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(pngFile)); 
       } catch (FileNotFoundException e) { 
        Log.e("WhitePngActivity", "Could not write " + pngFile, e); 
       } 

       // Immediately release the bitmap memory to avoid OutOfMemory exception 
       largeWhiteBitmap.recycle(); 
      } 
     }); 
    } 
} 
這個主要佈局

一起:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <Button 
     android:id="@+id/draw_to_bitmap" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="Click to draw to bitmap" /> 

</LinearLayout> 

你會得到像/mnt/sdcard/Pictures/big-white-image-with-view.png某處的位圖,它看起來是這樣的:

enter image description here

+0

寫得不錯:) – 2012-02-15 16:41:12