문제

좋아, 죄송합니다. 아마도 멍청한 질문이지만 좀 갇혀 있습니다.

그래서 내가하고있는 일 (ASP.NET 응용 프로그램에서)은 파일 시스템에서 이미지를로드하는 것입니다.

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

그런 다음 크기 조정을합니다.

tempImage = my awesomeResizingFunction(tempImage, newSize);

다음을 사용하여 다른 위치의 파일 시스템에 저장하려고합니다.

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

그리고 내가 얻는 것은이 오류입니다.

"A generic error occurred in GDI+."

이미지가 "OK"라는 것을 알고 있습니다. 브라우저에 글을 쓰고 크기가 크기가 큰 이미지를 볼 수 있기 때문에 저장하려고 할 때만 오류가 발생합니다. 나는 새롭고 갇혀 있는데, 나는 이것을 완전히 잘못하고 있습니까? (글쎄, 나는 그것이 분명하다고 생각하지만 당신은 내가 무슨 뜻인지 알고 있습니다 ...)

도움이 되었습니까?

해결책

plz이 코드를 시도해보십시오 ... 이미지 크기 조정 및 저장에 동일한 코드를 사용했습니다. 문제가 발생하면 plz에게 알려주세요.

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

여기서 FupProduct는 FileUpload Control ID입니다

다른 팁

OriginalPath와 NewPath가 다른 파일을 가리키는 것이 확실합니까? Image.FromFile을 사용하면 이미지에서 Dispose를 호출 할 때까지 파일이 잠긴 상태로 유지되므로 언급 한 예외로 이어질 수 있습니다. 대신 이미지를로드 할 수 있습니다.

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

이 접근법은 파일이 사용 블록의 끝에 닫히도록 보장합니다.

원본 이미지를 뒷받침하는 원래 스트림이 닫혔을 수 있습니까? 비트 맵 뒤의 스트림이 닫히면 GDI+ 오류가 발생합니다. 우리가 웹 사이트에 이미지 처리를 추가했을 때 이것에 많이 달렸습니다.

Visual Studio Debugger에서 비트 맵 객체를 열면 속성 값 대신 예외가 표시됩니까? 그렇다면 저장 작업에는 문제가되지 않지만 GDI+ 레이어는 객체, 기간을 처리하는 능력을 잃었습니다.

내가 찾은 것은 비트 맵에 속하는 메모리 스트림을 추적하고 모두 함께 유지해야했다는 것이 었습니다. 이미지를 조정하면 새로운 비트 맵 이미지가 포함 된 새로운 메모리 스트림이 생겼습니다.

나는이 간단한 수업을 만들었습니다 (여기에 불필요한 몇 가지 추가 속성을 다듬 었습니다).

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

이제 저는 웹 사이트에 업로드 된 이미지를 다루고 있었으며 ASP.NET이 요청에 첨부 된 스트림을 재활용했을 때 모든 갑작스런 이미지 작업이 뒤집어지기 시작했다는 것입니다. 따라서 이것이 가장 좋은 방법이든 아니든 내 솔루션은 업로드 스트림에서 내 MemoryStream으로 데이터를 복사하고 이미지를로드 하고이 컨테이너에 고착하는 것이 었습니다. 그리고 오래된 이미지에서 새로운 이미지를 만든 곳마다 항상 스트림과 이미지를 함께 유지했습니다.

이게 도움이 되길 바란다.

편집 : 이미지 크기 조정을하는 방법에 관심이 있습니다. 이것은 내가 우리를 어떻게했는지에 대한 스 니펫입니다.

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;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top