2009-02-27 7 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であるはずですが、もう一度:私はこれをmake-or-breakにすると思います。試してみる価値は、しかし...

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.Image!= null)_pictureBox.Image.Dispose()。 – ctacke

2

お使いのモバイルデバイスは、通常はディスクオプションにスワップ任意のメモリを持っていないので、あなたではなく、メモリにビットマップとしてあなたのイメージを保存することを選択したので、ディスク上のファイルよりも素早く携帯電話のメモリを消費します。あなたの "新しいBitmap()"行は大きなメモリを割り当てているので、そこに例外がスローされる可能性が非常に高いです。もう一つの候補は、大量のメモリを割り当てるCamera.ImageToByteArrayです。これはおそらくあなたがあなたのコンピュータで慣れているものではありませんが、あなたの携帯電話のためにこれは巨大です

それらを使用するまで、つまりウェブサービスに送るまで、ディスクに画像を保存してみてください。それらを表示するには、組み込みのコントロールを使用します。おそらく最もメモリ効率がよく、通常はイメージファイルを指すことができます。

乾杯

ニック

+0

「通常」はありません。 CEはまったくディスクにスワップする規定がないため、デバイスはそれをしません。 – ctacke