source

시스템에서 Out Of Memory 예외가 발생했습니다.그림그리기.Image.FromFile()

factcode 2023. 10. 21. 10:53
반응형

시스템에서 Out Of Memory 예외가 발생했습니다.그림그리기.Image.FromFile()

썸네일을 생성하는 이미지 업로더와 크로퍼가 있으며 다음 줄에서 Out Of Memory 예외가 발생하기도 합니다.

Dim bm As Bitmap = System.Drawing.Image.FromFile(imageFile)

오류의 발생은 매우 드물고 매우 드물지만, 저는 항상 오류의 원인이 무엇인지 알고 싶습니다.imageFile 변수는 서버일 뿐입니다.이미지 경로에 대한 MapPath입니다.

이전에 이 문제를 경험한 사람이 있는지, 원인이 무엇인지 아는 사람이 있는지 궁금합니다.혹시 이미지 크기인가요?

필요하다면 코드와 제가 가지고 있는 어떤 근거 있는 정보를 게시할 수 있지만, 이것에 대한 사람들의 의견을 듣고 싶습니다.

'Out Of Memory'란 것을 알아둘 가치가 있습니다.예외가 항상 메모리 부족을 의미하는 것은 아닙니다. 특히 파일을 다룰 때는 그렇지 않습니다.어떤 이유에서인지 손잡이가 부족할 경우에도 그럴 수 있다고 생각합니다.

비트맵은 다 처리하고 나면 다 처리하는 건가요?단일 이미지에 대해 반복적으로 발생합니까?

만약 이것이 나쁜 이미지 파일이 아니라 사실 정상적인 문제였다면.Image.FromFile파일 핸들을 열어두고 해결책은 다음과 같습니다.Image.FromStream대신.

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
   using (Image original = Image.FromStream(fs))
   {
      ...

명시적 사용Dispose() ,ausing()문 또는 값을 다음으로 설정null비트맵으로 문제를 해결하지는 못합니다.Image.FromFile.

그래서 앱이 잠시 실행되고 많은 파일을 연다면 사용을 고려해 볼 수 있습니다.Image.FromStream()대신.

이미지가 가득 찬 폴더에 대한 썸네일 이미지를 생성하는 중에 오늘 같은 문제가 발생했습니다."Out Of Memory"가 매번 같은 시점에 발생한 것으로 드러났습니다.변환할 이미지가 있는 폴더를 살펴보니 문제를 만들고 있는 파일이 sumbs.db였습니다.이미지 파일만 변환되고 문제가 해결되었는지 확인하기 위해 코드를 추가했습니다.

내 코드는 기본적으로

For Each imageFile as FileInfo in fileList
If imageFile.Extension = ".jpg" Or imageFile.Extension = ".gif" Then
    ...proceed with the conversion
End If
Next

도움이 되길 바랍니다.

같은 파일을 다른 곳에서 열지 않았는지도 확인합니다.파일을 두 번 열었을 때(파일이 있는 경우에도).열기() 메모리 부족예외도 던져졌습니다...

읽기 모드로 열 수도 있습니다. (두 곳에서 동시에 사용하려면)

 public Image OpenImage(string previewFile)
        {
            FileStream fs = new FileStream(previewFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            return Image.FromStream(fs);
        }

이는 이미지 파일이 손상된 경우에 발생합니다.이것은 나쁜 오류 메시지입니다. 왜냐하면 메모리는 그것과 아무 관련이 없기 때문입니다.코딩을 해보지는 못했지만, 시도해보면 프로그램이 휘어지는 것을 막을 수 있을 것입니다.

오늘 이미지 크기를 조정한 후 잘라낼 때도 비슷한 문제가 있었습니다. 이 코드를 사용하여 이미지 크기를 조정했습니다.

private static Image resizeImage(Image imgToResize, Size size)
{
   int sourceWidth = imgToResize.Width;
   int sourceHeight = imgToResize.Height;

   float nPercent = 0;
   float nPercentW = 0;
   float nPercentH = 0;

   nPercentW = ((float)size.Width / (float)sourceWidth);
   nPercentH = ((float)size.Height / (float)sourceHeight);

   if (nPercentH < nPercentW)
      nPercent = nPercentH;
   else
      nPercent = nPercentW;

   int destWidth = (int)(sourceWidth * nPercent);
   int destHeight = (int)(sourceHeight * nPercent);

   Bitmap b = new Bitmap(destWidth, destHeight);
   Graphics g = Graphics.FromImage((Image)b);
   g.InterpolationMode = InterpolationMode.HighQualityBicubic;

   g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
   g.Dispose();

   return (Image)b;
}

그리고 이 작물의 코드는...

private static Image cropImage(Image img, Rectangle cropArea)
{
   Bitmap bmpImage = new Bitmap(img);
   Bitmap bmpCrop = bmpImage.Clone(cropArea,
   bmpImage.PixelFormat);
   return (Image)(bmpCrop);
}

위의 코드를 이렇게 불렀더니...

Image img = Image.FromFile(@"C:\Users\****\Pictures\image.jpg");
img = ImageHandler.ResizeImage(img, new Size(400, 300));
img = ImageHandler.CropImage(img, new Rectangle(0, 25, 400, 250));
long quality = 90;

크롭 부분에서 계속 오류가 났는데 리사이저는 잘 작동했습니다!

알고 보니, 리사이저 안에서 일어난 일은 크롭 기능에 오류를 던지는 것이었습니다.크기를 조정한 계산 결과 이미지의 실제 치수는 제가 넘겨준 400이 아니라 399 정도가 되었습니다.

그래서 제가 크롭에 대한 논쟁으로 400을 넘겼을 때, 그것은 400px 너비 bmp의 399px 너비 이미지를 크롭하려다가 메모리 부족 오류를 던졌습니다!

위 코드의 대부분은 http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing 에서 찾을 수 있습니다.

영상이 아이콘인 경우 다음 기능과 같이 다른 로딩 처리가 필요합니다.

public static Image loadImage(string imagePath)
    {
        Image loadedImage = null;
        if (!File.Exists(imagePath)) return loadedImage;
        try
        {
            FileInfo fileInfo = new FileInfo(imagePath);
            if (fileInfo.Extension.Equals(".jpg") || fileInfo.Extension.Equals(".jpeg") ||
               fileInfo.Extension.Equals(".bmp") || fileInfo.Extension.Equals(".png") ||
               fileInfo.Extension.Equals(".gif"))
            {
                loadedImage = Image.FromFile(imagePath);
            }
            else if (fileInfo.Extension.Equals(".ico"))
            {
                Bitmap aBitmap = Bitmap.FromHicon(new
                                           Icon(imagePath, new Size(200, 200)).Handle);
                loadedImage = ImageFuncs.ResizeImage(aBitmap, new Size(30, 30));
            }
        }
        catch (Exception eLocal)
        {
            MessageBox.Show(imagePath + " loading error: " + eLocal.Message);
        }
        return loadedImage;
    }

TIFF를 PDF로 변환하기 위해 작성한 유틸리티에도 동일한 문제가 발생했습니다.종종 당신과 같은 라인에서 "기억상실" 오류가 발생하곤 했습니다.

System.Drawing.Image.FromFile(imageFile)

그리고 파일 확장자가 ".tiff"일 때만 오류가 발생하고 확장자가 ".tif"인 상태에서 이름을 변경한 후에는 정상적으로 작동했습니다.

코드에서 이미지 뷰어를 사용하여 이미지를 열 수 있는지 확인하고 싶은 다른 위치를 확인하기 전에 동일한 문제가 발생했으며 이미지가 a임에도 불구하고 손상/손상되었음을 확인했습니다.1KB 크기의 PNG 파일.동일한 위치에 새 이미지를 추가한 다음 잘 작동했습니다.

Tiff 파일을 일괄 처리하는 데도 문제가 있습니다.대부분의 파일이 예외를 허용하지 않지만 ASP에서 "Out of Memory" 예외를 허용하는 파일은 거의 없습니다.NET 4.0.저는 바이너리 데이터를 사용하여 몇 개의 파일과 동일한 폴더 내에서 그 이유를 알아냈습니다.ASP에 대한 권한 문제가 될 수 없습니다.다른 파일이 작업 파일이기 때문에 NET ASPNET 또는 NETWORK SERVICE 계정입니다.

iTextSharp.text를 열었습니다.이미지 클래스에서 GetInstance()에 대해 오버로드된 메서드가 많이 있음을 발견했습니다.다음 코드를 사용하여 문제를 해결했습니다. 참고: 문제가 있는 파일에 대해 catch block이 실행됩니다.

                iTextSharp.text.Image image = null;
            try
                {
                    var imgStream = GetImageStream(path);
                     image = iTextSharp.text.Image.GetInstance(imgStream);
                }
                catch {
                    iTextSharp.text.pdf.RandomAccessFileOrArray ra = null;
                    ra = new iTextSharp.text.pdf.RandomAccessFileOrArray(path);
                    image = iTextSharp.text.pdf.codec.TiffImage.GetTiffImage(ra, 1);

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

                }

IIS에서 서비스를 제공하는 경우 응용프로그램 풀을 재활용해 보십시오.이것은 저에게 비슷한 이미지 업로드 "Out of Memory" 오류를 해결해 주었습니다.

여전히 오류가 발생하는 최소 양식 예제를 만들었습니다.

        private void button1_Click(object sender, EventArgs e)
    {
        string SourceFolder = ImageFolderTextBox.Text;
        string FileName = "";
        DirectoryInfo Mydir = new DirectoryInfo(SourceFolder);
        FileInfo[] JPEGS = Mydir.GetFiles("*.jpg");
        for (int counter = 0; counter < JPEGS.Count(); counter++)
        {
            FileName = Mydir + "\\" + JPEGS[counter].Name;
            //using (Image MyImage = System.Drawing.Image.FromFile(FileName))
            using (FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                StatusBtn.BackColor = Color.Green;
            }
        }
    }

저는 이미지를 이용하여 댓글을 단 두 개의 아웃라인을 모두 사용해 보았습니다.From File() 및 FileStream()을 사용하는 행.둘 다 파일 오류가 발생했습니다.

이미지.FromFile() 오류: 시스템.OutOf Memory예외: '메모리 부족'

파일 스트림() 오류: 시스템입니다.권한 없는 액세스예외: '경로에 접근' E:\DCIM\100Canon\dsc_7218.jpg'이(가) 거부되었습니다.

오류가 발생하는 줄 바로 앞에 중단점을 두었고 윈도우 이미지 뷰어를 사용하여 이미지 파일을 열 수 있습니다.그런 다음 뷰어를 닫았고 다음 줄로 이동하여 오류가 발생한 후 Windows 뷰어로 더 이상 이미지를 볼 수 없습니다.대신 파일 접근 권한이 없다는 메시지가 나타납니다.저는 파일을 삭제할 수 있습니다.

이 오류는 반복될 수 있습니다.10번 넘게 했어요.매번 오류가 발생하면 FileName에 사용된 파일을 삭제합니다.

모든 파일이 손상되지 않은 것으로 확인되었습니다.

이미지를 사용한 나의 원래 코드.FromFile()은 2년 전에 컴파일했을 때 잘 작동했습니다.사실 .exe 파일은 잘 실행됩니다.코드의 다른 곳에서 사소한 변경을 했는데 이 오류 없이는 코드가 컴파일되지 않는 것을 알고 놀랐습니다.저는 이 페이지의 정보를 바탕으로 FileStream() 방법을 시도했습니다.

언급URL : https://stackoverflow.com/questions/1108607/out-of-memory-exception-on-system-drawing-image-fromfile

반응형