Pregunta

Ok, lo siento, esta es probablemente una pregunta novata pero estoy un poco atascado.

Entonces, lo que estoy haciendo (en mi aplicación asp.net) es cargar una imagen del sistema de archivos:

System.Drawing.Image tempImage;
tempImage = System.Drawing.Image.FromFile(HttpContext.Server.MapPath(originalPath));

Luego hago un cambio de tamaño:

tempImage = my awesomeResizingFunction(tempImage, newSize);

e intenta guardarlo en el sistema de archivos en otra ubicación usando esto:

string newPath = "/myAwesomePath/newImageName.jpg";
tempImage.Save(newPath);

y lo que obtengo es este error:

"A generic error occurred in GDI+."

Sé que la imagen está "bien" porque puedo escribirlo en el navegador y ver la imagen redimensionada, solo aparece el error cuando intento guardarlo. Soy un poco nuevo y atascado, ¿estoy haciendo esto totalmente mal? (Bueno, supongo que es obvio, pero sabes a lo que me refiero ...)

¿Fue útil?

Solución

por favor intente este código ... He usado el mismo código para cambiar el tamaño de la imagen y guardarla. si tienes algún problema, por favor avísame.

System.Drawing.Bitmap bmpOut = new System.Drawing.Bitmap(NewWidth, NewHeight);
    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmpOut);
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
    g.FillRectangle(System.Drawing.Brushes.White, 0, 0, NewWidth, NewHeight);
    g.DrawImage(new System.Drawing.Bitmap(fupProduct.PostedFile.InputStream), 0, 0, NewWidth, NewHeight);
    MemoryStream stream = new MemoryStream();
    switch (fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.') + 1).ToLower())
    {
        case "jpg":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            break;
        case "jpeg":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            break;
        case "tiff":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
            break;
        case "png":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            break;
        case "gif":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
            break;
    }
    String saveImagePath = Server.MapPath("../") + "Images/Thumbnail/" + fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.'));
    bmpOut.Save(saveImagePath);

donde fupProduct es la ID de control de carga de archivos

Otros consejos

¿Está seguro de que originalPath y newPath apuntan a diferentes archivos? Cuando usa Image.FromFile, el archivo permanece bloqueado hasta que llame a Dispose en la imagen, lo que puede conducir a la excepción que mencionó. En su lugar, puede cargar la imagen así:

Image tempImage = null;
using (FileStream fs = new FileStream(originalPath, FileMode.Open, FileAccess.Read))
{
    tempImage = Image.FromStream(fs);
}
...

Este enfoque garantiza que el archivo se cierre al final del bloque de uso

¿Es posible que la secuencia original que respalda la imagen original se haya cerrado? Si la secuencia detrás de un mapa de bits se ha cerrado, comienza a recibir errores de GDI +. Me encontré mucho con esto cuando agregamos el procesamiento de imágenes a nuestro sitio web.

Si abre el objeto Bitmap en el depurador de Visual Studio, ¿ve excepciones en lugar de los valores de las propiedades? Si es así, no es un problema con la operación de guardar, pero la capa GDI + ha perdido la capacidad de procesar el objeto, punto.

Lo que encontré fue que necesitaba hacer un seguimiento de los MemoryStreams que pertenecen a mis Bitmaps y mantenerlos todos juntos. Cambiar el tamaño de una imagen resultó en un nuevo MemoryStream con una nueva imagen de mapa de bits.

Terminé creando esta clase simple (recorté algunas propiedades adicionales innecesarias aquí):

public class UploadedImage : IDisposable
{
    private Bitmap _img = null;
    private Stream _baseStream = null;


    /// <summary>
    /// The image object.  This must always belong to BaseStream, or weird things can happen.
    /// </summary>
    public Bitmap Img
    {
        [DebuggerStepThrough]
        get { return _img; }
        [DebuggerStepThrough]
        set { _img = value; }
    }

    /// <summary>
    /// The stream that stores the image.  This must ALWAYS belong to Img, or weird things can happen.
    /// </summary>
    public Stream BaseStream
    {
        [DebuggerStepThrough]
        get { return _baseStream; }
        [DebuggerStepThrough]
        set { _baseStream = value; }
    }

    [DebuggerStepThrough]
    public void Dispose()
    {
        if (Img != null)
            Img.Dispose();

        if (BaseStream != null)
            BaseStream.Close();

        _attached = false;
    }
}

Ahora, estaba lidiando con imágenes cargadas en nuestro sitio web, y lo que encontré fue que cuando Asp.Net recicló el flujo adjunto a la Solicitud, todas las operaciones repentinas de imágenes comenzaron a cambiar. Entonces, mi solución, si esta era la mejor manera de hacerlo o no, era copiar los datos de la transmisión de carga a mi propio MemoryStream, cargar la imagen desde allí y pegar ambos en este contenedor. Y siempre que creaba una nueva imagen a partir de una anterior, siempre mantenía la secuencia y la imagen juntas.

Espero que esto ayude.

EDITAR: También estoy interesado en ver cómo estás cambiando el tamaño de la imagen. Este es un fragmento de cómo hice el nuestro:

temp = new Bitmap(newWidth, newHeight, PIXEL_FORMAT);
temp.SetResolution(newHorizontalRes, newVerticalRes);
gr = Graphics.FromImage(temp);

//
// This copies the active frame from 'img' to the new 'temp' bitmap.
// Also resizes it and makes it super shiny.  Sparkle on, mr image dude.
// 
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.SmoothingMode = SmoothingMode.HighSpeed;
gr.PageUnit = GraphicsUnit.Pixel;
gr.DrawImage(img, rect);

//
// Image copied onto the new bitmap.  Save the bitmap to a fresh memory stream.
//
retval = new UploadedImage();
retval.BaseStream = (Stream)(new MemoryStream());

temp.Save(retval.BaseStream, ImageFormat.Jpeg);
retval.Img = temp;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top