我正在开发一种使用移动装置进行拍照并使用一个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);
}
有帮助吗?

解决方案

我怀疑你是持有到引用。作为未成年人的原因,请注意使用时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等,以确保事情尽快释放。

其他提示

您的移动设备通常没有任何内存交换到磁盘选项,所以既然你选择将图像存储在内存中,而不是磁盘上的文件的位图,你很快就会消耗你手机的内存。您的“新位图()”行分配大块的内存,因此它很可能抛出异常出现。另一个竞争者是你Camera.ImageToByteArray将分配大量内存。这可能不是大到你已经习惯了与您的计算机是什么,但对于您的手机,这是巨大的。

建议保持图片在磁盘上,直到你使用它们,即直到将它们发送到Web服务。为了显示他们,用你的内置控件,它们可能是最有效的记忆和您通常可以将它们指向的图像文件。

干杯

的Nik

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top