Pergunta

Ok, me desculpe, esta é provavelmente uma questão de noob, mas eu estou meio preso.

Então, o que estou fazendo (no meu aplicativo asp.net) está carregando uma imagem do sistema de arquivos:

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

Então eu fazer alguma redimensionamento:

tempImage = my awesomeResizingFunction(tempImage, newSize);

e pretende guardá-lo para o sistema de arquivos em outro local usando o seguinte:

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

eo que eu vejo é este erro:

"A generic error occurred in GDI+."

Eu sei que a imagem é "ok" porque eu posso escrevê-lo para o navegador e ver a imagem redimensionada, eu só recebo o erro ao tentar salvá-lo. Eu estou meio novo e preso, estou fazendo isso totalmente errado? (Bem, eu acho que é óbvio, mas você sabe o que quero dizer ...)

Foi útil?

Solução

plz tente este código ... Eu tenho usado o mesmo código para redimensionar imagem e poupança. se tiver qualquer problema, então plz me avise.

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

onde fupProduct é o controle fileupload ID

Outras dicas

Você tem certeza que o OriginalPath e ponto newpath a diferentes arquivos? Quando você usa Image.FromFile, os restos de arquivo bloqueado até que você chamar Dispose sobre a imagem, que pode levar a exceção que você mencionou. Você poderia carregar a imagem como aquela vez:

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

Esta abordagem garante que o arquivo é fechado no final do bloco usando

É possível o fluxo original apoiando a imagem original foi fechado? Se o fluxo atrás de um Bitmap foi fechado, você começar a receber erros GDI +. Corri para este muito quando adicionamos processamento de imagem para o nosso site.

Se você abrir o objeto Bitmap no depurador Visual Studio, você vê exceções em vez dos valores das propriedades? Se assim for, não é um problema com a operação de salvamento, mas a camada GDI + perdeu a capacidade de processar o objeto, período.

O que descobri foi que eu precisava para manter o controle dos MemoryStreams pertencentes aos meus mapas de bits e mantê-los todos juntos. Redimensionar uma imagem resultou em uma nova MemoryStream uma nova imagem de bitmap.

I acabou criando esta classe simples (aparadas algumas propriedades extras desnecessários aqui):

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

Agora, eu estava lidando com imagens enviadas ao nosso site, eo que eu encontrei foi que, quando Asp.Net reciclados o fluxo anexado ao pedido, todas as operações de imagem súbitas começou pirando. Então, a minha solução, se esta era a melhor maneira de fazê-lo ou não, era para copiar os dados do fluxo de upload para o meu próprio MemoryStream, carregar a imagem daquele, e ficar tanto neste recipiente. E onde quer que eu criei uma nova imagem a partir de um velho, eu sempre mantive o fluxo ea imagem juntos.

Espero que isso ajude.

EDIT: Eu também estou interessado em ver como você está fazendo o redimensionamento da imagem. Este é um trecho de como eu fiz nosso:

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top