2009-02-27 148 views
3

我正在開發一個應用程序,使用移動設備拍攝照片並使用web服務發送。但是在拍完4張照片後,我在下面的代碼中得到了OutOfMemoryException。我嘗試撥打GC.Collect(),但它也沒有幫助。也許這裏的某個人可能會給我一個如何處理這個問題的建議。OutOfMemoryException在移動設備

public static Bitmap TakePicture() 
{ 
    var dialog = new CameraCaptureDialog 
    { 
     Resolution = new Size(1600, 1200), 
     StillQuality = CameraCaptureStillQuality.Default 
    }; 

    dialog.ShowDialog(); 

    // If the filename is empty the user took no picture 
    if (string.IsNullOrEmpty(dialog.FileName)) 
     return null; 

    // (!) The OutOfMemoryException is thrown here (!) 
    var bitmap = new Bitmap(dialog.FileName); 

    File.Delete(dialog.FileName); 

    return bitmap; 
} 

的功能是由一個事件處理函數調用:

private void _pictureBox_Click(object sender, EventArgs e) 
{ 
    _takePictureLinkLabel.Visible = false; 

    var image = Camera.TakePicture(); 
    if (image == null) 
     return; 

    image = Camera.CutBitmap(image, 2.5); 
    _pictureBox.Image = image; 

    _image = Camera.ImageToByteArray(image); 
} 

回答

5

我懷疑你是持有到引用。作爲一個小原因,請注意,使用ShowDialog時對話框不會自行處理,因此應該是using對話框(儘管我希望GC仍然會收集一個未處理但未引用的對話框)。

同樣,你應該可能是using的形象,但再次:不知道我會期望這樣做或打破;值得一試,但...

public static Bitmap TakePicture() 
{ 
    string filename; 
    using(var dialog = new CameraCaptureDialog 
    { 
     Resolution = new Size(1600, 1200), 
     StillQuality = CameraCaptureStillQuality.Default 
    }) { 

     dialog.ShowDialog(); 
     filename = dialog.FileName; 
    }  
    // If the filename is empty the user took no picture 
    if (string.IsNullOrEmpty(filename)) 
     return null; 

    // (!) The OutOfMemoryException is thrown here (!) 
    var bitmap = new Bitmap(filename); 

    File.Delete(filename); 

    return bitmap; 
} 

private void _pictureBox_Click(object sender, EventArgs e) 
{ 
    _takePictureLinkLabel.Visible = false; 

    using(var image = Camera.TakePicture()) { 
     if (image == null) 
      return; 

     image = Camera.CutBitmap(image, 2.5); 
     _pictureBox.Image = image; 

     _image = Camera.ImageToByteArray(image); 
    } 
} 

我還有點謹慎的CutBitmap等,以確保事情儘快釋放。

+1

我會稍微修改你的代碼 - 它設置picturebox圖像,我會首先處理任何現有的圖像,如果(_pictureBox.Image!= null)_pictureBox.Image.Dispose()。 – ctacke 2009-02-27 14:59:13

2

您的移動設備通常沒有任何內存交換到磁盤選項,所以既然你選擇將圖像保存爲位圖在內存中,而比磁盤上的文件,你很快消耗手機的內存。您的「新Bitmap()」行分配一大塊內存,所以很可能會拋出異常。另一個競爭者是你的Camera.ImageToByteArray,它將分配大量的內存。這可能並不是很大,但你的手機,這是巨大的

嘗試保留在磁盤上的圖片,直到你使用它們,即直到發送到web服務。要顯示它們,請使用內置控件,它們可能是內存效率最高的,並且通常可以將它們指向圖像文件。

乾杯

+0

有沒有「通常」它。 CE沒有任何規定來交換磁盤,所以沒有設備。 – ctacke 2009-02-27 14:59:52