Pregunta

Estoy desarrollando una aplicación que utiliza un dispositivo móvil para tomar una foto y enviarla usando un servicio web. Pero después de que he tomado 4 fotos Recibo un OutOfMemoryException en el código de abajo. Traté de llamar GC.Collect() pero no ayudó tampoco. Tal vez alguien aquí podría ser dame un consejo de cómo manejar este problema.

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

La función es llamada por un controlador de eventos:

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);
}
¿Fue útil?

Solución

Sospecho que se están aferrando a las referencias. Como una causa menor, tenga en cuenta que los diálogos no se dispongan al utilizar ShowDialog, por lo que debe ser using el cuadro de diálogo (aunque yo esperaría GC para recoger aún no vendida, pero un diálogo no referenciado).

Del mismo modo, probablemente debería ser using la imagen, pero una vez más: no estoy seguro de que yo esperaría esto para hacer todo o nada; vale la pena intentarlo, aunque ...

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

También sería un poco cauteloso de la CutBitmap etc, para asegurar que las cosas son liberados lo antes posible.

Otros consejos

Su dispositivo móvil por lo general no tiene ninguna memoria de intercambio de opción de disco, por lo que desde decide guardar sus imágenes como mapas de bits en la memoria en lugar de los archivos en el disco, que consume rápidamente la memoria del teléfono. Su línea de "nuevo mapa de bits ()" asigna una gran cantidad de memoria, por lo que es muy probable que emitir la excepción allí. Otro candidato es su Camera.ImageToByteArray que asignar una gran cantidad de memoria. Esto probablemente no es grande para lo que estamos acostumbrados con el ordenador, pero para su dispositivo móvil este es gigantesco

Trate de mantener las imágenes en el disco hasta que los utilices, es decir, hasta que enviarlos al servicio web. Para mostrarlos, utilizar sus controles integrados, que son probablemente el más eficiente de la memoria y por lo general se les puede señalar a los archivos de imagen.

Saludos

Nik

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top