3

モバイルデバイスを使用して写真を撮り、Web サービスを使用して送信するアプリケーションを開発しています。しかし、4枚の写真を撮った後OutOfMemoryException、以下のコードを取得しています。電話をかけてみGC.Collect()ましたが、どちらも役に立ちませんでした。ここにいる誰かが、この問題を処理する方法についてアドバイスをくれるかもしれません。

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);
}
4

2 に答える 2

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また、物事ができるだけ早くリリースされるように、などにも少し注意を払います。

于 2009-02-27T08:36:17.853 に答える
2

モバイル デバイスには通常、ディスクへのメモリ スワッピング オプションがないため、画像をディスク上のファイルではなくビットマップとしてメモリに保存することを選択すると、携帯電話のメモリがすぐに消費されます。「new Bitmap()」行は大量のメモリを割り当てるため、そこで例外がスローされる可能性が非常に高くなります。別の候補は、大量のメモリを割り当てる Camera.ImageToByteArray です。これはおそらく、コンピューターで慣れ親しんだものには大きくありませんが、モバイルの場合は巨大です

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

乾杯

ニック

于 2009-02-27T08:34:54.987 に答える