3

我正在开发一个使用移动设备拍摄照片并使用网络服务发送的应用程序。但是在我拍了 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 回答