locked
Generic error in GDI+ RRS feed

  • Question

  • User-1786262203 posted

    Hi, can you tell me what's wrong with my code.

    Sometimes the code got an exception like this:

    Error Log:
    ExternalException: A generic error occurred in GDI+.
       at System.Drawing.Bitmap.GetHbitmap(Color background)
       at System.Drawing.Bitmap.GetHbitmap()
       at E_Store.Resources.BaseImage.<>c__DisplayClass8.<SaveImage>b__2() in D:\Users\Yunus Kurniawan\E-Store Proj\E-Store\E-Store\Resources\BaseImage.Statics.Methods.Helpers.cs:line 61
       at E_Store.Resources.BaseImage.SaveImage(Image image) in D:\Users\Yunus Kurniawan\E-Store Proj\E-Store\E-Store\Resources\BaseImage.Statics.Methods.Helpers.cs:line 28
       at E_Store.Resources.Products.Image.GetRawImage() in D:\Users\Yunus Kurniawan\E-Store Proj\E-Store\E-Store\Resources\Products\Image..Methods.Overrides.cs:line 58
       at E_Store.Resources.BaseImage.ProcessRequest(HttpContext context) in D:\Users\Yunus Kurniawan\E-Store Proj\E-Store\E-Store\Resources\BaseImage.IHttpHandler.cs:line 36
       at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

    I am sure every disposable object i wrapped in using block to ensure the object disposed well.

    I am confusing why sometimes i got the exception (usually working fine).
    There are no useful information inside the exception, just a generic error. It's difficult to fix. 

    Some part of the code (sorry, much of code lines):

    protected override byte[] GetRawImage()
    {
      var productID = GetProductID();
      if (productID == null) return null;
    
    
    
      using (var models = new Models.ModelsDataContext())
      {
        using (var image =
          (
            from product in models.Products
            where (
              (product.ID == productID)
              &&
              (product.Image != null)
            )
            select product.Image
          )
          .FirstOrDefault()
        )
        {
          return SaveImage(image);
        } // using
      } // using
    }
    
    
    protected static byte[] SaveImage(System.Drawing.Image image)
    {
      if (image == null) return null;
    
    
    
      return (new Func<byte[]>(() => {
        using (var stream = new MemoryStream())
        {
          if (image.FrameDimensionsList.Length > 1)
          {
            #region save as gif/wmf
            using (var encoderParameters = new EncoderParameters(1))
            {
              using (var encoderParameter1 = new EncoderParameter(Encoder.RenderMethod, EncoderValue.RenderProgressive.ToString()))
              {
                encoderParameters.Param[0] = encoderParameter1;
    
    
    
                image.Save(
                  stream,
                  (new Func<ImageCodecInfo>(() => {
                    var mime = (new Func<string>(() => {
                      var format = image.RawFormat;
                      if (format == ImageFormat.Gif) return "image/gif";
                      if (format == ImageFormat.Wmf) return "image/wmf";
                      return "image/gif";
                    }).Invoke());
    
                    return
                      ImageCodecInfo.GetImageEncoders()
                      .First(enc => string.Equals(mime, enc.MimeType, StringComparison.InvariantCultureIgnoreCase))
                      ;
                  }).Invoke()),
                  encoderParameters
                );
              } // using
            } // using
            #endregion save as gif/wmf
          }
          else
          {
            #region save as png/jpeg
            var bmp = (image as Bitmap) ?? new Bitmap(image);
            try
            {
              var bmpSrc = Imaging.CreateBitmapSourceFromHBitmap(
                /*bitmap = */bmp.GetHbitmap(),
                /*pallete = */IntPtr.Zero,
                /*sourceRect = */Int32Rect.Empty,
                /*sizeOptions = */BitmapSizeOptions.FromEmptyOptions()
              );
    
              var fcb = new FormatConvertedBitmap(
                /*bitmapSource = */bmpSrc,
                /*destinationFormat = */bmpSrc.Format,
                /*destinationPallete = */bmpSrc.Palette,
                1d
              );
    
    
              (new Func<BitmapEncoder>(() => {
                if ((image.PixelFormat & System.Drawing.Imaging.PixelFormat.Alpha) == System.Drawing.Imaging.PixelFormat.Alpha)
                {
                  // image has alpha colors, save it as png:
    
                  return new PngBitmapEncoder() {
                    Frames = {
                      BitmapFrame.Create(fcb)
                    },
                    Interlace = PngInterlaceOption.On,
                  };
                }
                else
                {
                  // image didn't have alpha colors, save it as jpg:
    
                  return new JpegBitmapEncoder() {
                    Frames = {
                      BitmapFrame.Create(fcb)
                    },
                    QualityLevel = 90,
                  };
                } // if
              }).Invoke())
              .Save(stream)
              ;
            }
            finally
            {
              if (!object.ReferenceEquals(bmp, image)) bmp.Dispose();
            } // try
            #endregion save as png/jpeg
          } // if
    
    
    
          return stream.ToArray();
        } // using
      }).Invoke());
    }
    
    Tuesday, January 17, 2012 8:48 PM

All replies

  • User-821857111 posted

    Most often, a Generic GDI Error results from there being insufficient permissions for the user account on the folder that you are trying to save the image to. The user is most often NETWORK SERVICE. Make sure it has Write permissions on the folder.

    Wednesday, January 18, 2012 2:01 AM
  • User-1786262203 posted

    Most often, a Generic GDI Error results from there being insufficient permissions for the user account on the folder that you are trying to save the image to. The user is most often NETWORK SERVICE. Make sure it has Write permissions on the folder.

    Hi, i am using MemoryStream as the temporary storage, then emit the bytes to the http output.

    I have 4 gb of ram on the server, only 50% of the memory usage while in high http traffic.

    When the error occurs, i restart the IIS and then everything working fine. After several hours/days the GDI exception occurs and i must restart the IIS again, again...

    Wednesday, January 18, 2012 3:42 AM