调整图像 gdi 大小+图形.net

发布于 2024-08-08 22:27:02 字数 1860 浏览 1 评论 0原文

我有这种方法可以缩小我正在开发的网站的图像:

static byte[] createSmallerImage(
   BlogPhoto blogPhoto, 
   int newMaxWidth, 
   int newMaxHeight)
{
  Image img;
  using (MemoryStream originalImage = 
           new MemoryStream(blogPhoto.BlogPhotoImage))
  {
    img = Image.FromStream(originalImage);
  }

  int newWidth;
  int newHeight;
  byte[] arr;

  if (img.Width > img.Height)
  {
    if (img.Width <= newMaxWidth)
    {

      using (MemoryStream thumbStr = new MemoryStream())
      {
        img.Save(thumbStr, ImageFormat.Jpeg);
        img.Dispose();
        arr = thumbStr.ToArray();
      }
      return arr;
    }

    newWidth = newMaxWidth;
    newHeight = 
       (int)(((float)newWidth / (float)img.Width) * (float)img.Height);
  }
  else
  {
    if (img.Height <= newMaxHeight)
    {

      using (MemoryStream thumbStr = new MemoryStream())
      {
        img.Save(thumbStr, ImageFormat.Jpeg);
        img.Dispose();
        arr = thumbStr.ToArray();
      }
      return arr;
    }

    newHeight = newMaxHeight;
    newWidth = 
      (int)(((float)newHeight / (float)img.Height) * (float)img.Width);
  }

  Image thumb = new Bitmap(newWidth, newHeight);

  Graphics g = Graphics.FromImage(thumb);
  g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  g.SmoothingMode = SmoothingMode.HighQuality;
  g.PixelOffsetMode = PixelOffsetMode.HighQuality;
  g.CompositingQuality = CompositingQuality.HighQuality;

  g.DrawImage(img, 0f, 0f, (float)newWidth, (float)newHeight);


  using (MemoryStream thumbStr = new MemoryStream())
  {
    thumb.Save(thumbStr, ImageFormat.Jpeg);
    arr = thumbStr.ToArray();
  }

  g.Dispose();
  img.Dispose();

  return arr;
}

大多数时候它工作得很好,但有时它会给我这个例外:GDI+ 中发生一般错误。错误代码-2147467259。来源:“系统.绘图”。这种情况发生在 Image.Save(... 我试图使这段代码尽可能具有防御性,但我仍然没有得到导致这种情况的原因。如果有人知道答案那就太好了,也欢迎批评。

I have this method for shrinking down an image for a website that I'm working on:

static byte[] createSmallerImage(
   BlogPhoto blogPhoto, 
   int newMaxWidth, 
   int newMaxHeight)
{
  Image img;
  using (MemoryStream originalImage = 
           new MemoryStream(blogPhoto.BlogPhotoImage))
  {
    img = Image.FromStream(originalImage);
  }

  int newWidth;
  int newHeight;
  byte[] arr;

  if (img.Width > img.Height)
  {
    if (img.Width <= newMaxWidth)
    {

      using (MemoryStream thumbStr = new MemoryStream())
      {
        img.Save(thumbStr, ImageFormat.Jpeg);
        img.Dispose();
        arr = thumbStr.ToArray();
      }
      return arr;
    }

    newWidth = newMaxWidth;
    newHeight = 
       (int)(((float)newWidth / (float)img.Width) * (float)img.Height);
  }
  else
  {
    if (img.Height <= newMaxHeight)
    {

      using (MemoryStream thumbStr = new MemoryStream())
      {
        img.Save(thumbStr, ImageFormat.Jpeg);
        img.Dispose();
        arr = thumbStr.ToArray();
      }
      return arr;
    }

    newHeight = newMaxHeight;
    newWidth = 
      (int)(((float)newHeight / (float)img.Height) * (float)img.Width);
  }

  Image thumb = new Bitmap(newWidth, newHeight);

  Graphics g = Graphics.FromImage(thumb);
  g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  g.SmoothingMode = SmoothingMode.HighQuality;
  g.PixelOffsetMode = PixelOffsetMode.HighQuality;
  g.CompositingQuality = CompositingQuality.HighQuality;

  g.DrawImage(img, 0f, 0f, (float)newWidth, (float)newHeight);


  using (MemoryStream thumbStr = new MemoryStream())
  {
    thumb.Save(thumbStr, ImageFormat.Jpeg);
    arr = thumbStr.ToArray();
  }

  g.Dispose();
  img.Dispose();

  return arr;
}

Most of the time it works great but sometimes it gives me this exception:A generic error occurred in GDI+. Error Code -2147467259. Source: "System.Drawing". This occurs on the Image.Save(... I tried to make this code as defensive as possible but am still not getting whats causing this. If someone knows the answer that'd be great, critiques are welcome too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

江南月 2024-08-15 22:27:02

我个人使用这段代码,没有流(不过我不关心性能)来调整图片大小:

public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
 {
     Image imgPhoto = Image.FromFile(stPhotoPath); 

     int sourceWidth = imgPhoto.Width;
     int sourceHeight = imgPhoto.Height;

     //Consider vertical pics
    if (sourceWidth < sourceHeight)
    {
        int buff = newWidth;

        newWidth = newHeight;
        newHeight = buff;
    }

    int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
    float nPercent = 0, nPercentW = 0, nPercentH = 0;

    nPercentW = ((float)newWidth / (float)sourceWidth);
    nPercentH = ((float)newHeight / (float)sourceHeight);
    if (nPercentH < nPercentW)
    {
        nPercent = nPercentH;
        destX = System.Convert.ToInt16((newWidth -
              (sourceWidth * nPercent)) / 2);
    }
    else
    {
        nPercent = nPercentW;
        destY = System.Convert.ToInt16((newHeight -
              (sourceHeight * nPercent)) / 2);
    }

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


    Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
              PixelFormat.Format24bppRgb);

    bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
             imgPhoto.VerticalResolution);

    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.Clear(Color.Black);
    grPhoto.InterpolationMode =
        InterpolationMode.HighQualityBicubic;

    grPhoto.DrawImage(imgPhoto,
        new Rectangle(destX, destY, destWidth, destHeight),
        new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
        GraphicsUnit.Pixel);

    grPhoto.Dispose();
    return bmPhoto;
}

希望这会有所帮助。

I personally use this code, with no streams (I don't care about perfs, though) for resizing a picture:

public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
 {
     Image imgPhoto = Image.FromFile(stPhotoPath); 

     int sourceWidth = imgPhoto.Width;
     int sourceHeight = imgPhoto.Height;

     //Consider vertical pics
    if (sourceWidth < sourceHeight)
    {
        int buff = newWidth;

        newWidth = newHeight;
        newHeight = buff;
    }

    int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
    float nPercent = 0, nPercentW = 0, nPercentH = 0;

    nPercentW = ((float)newWidth / (float)sourceWidth);
    nPercentH = ((float)newHeight / (float)sourceHeight);
    if (nPercentH < nPercentW)
    {
        nPercent = nPercentH;
        destX = System.Convert.ToInt16((newWidth -
              (sourceWidth * nPercent)) / 2);
    }
    else
    {
        nPercent = nPercentW;
        destY = System.Convert.ToInt16((newHeight -
              (sourceHeight * nPercent)) / 2);
    }

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


    Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
              PixelFormat.Format24bppRgb);

    bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
             imgPhoto.VerticalResolution);

    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.Clear(Color.Black);
    grPhoto.InterpolationMode =
        InterpolationMode.HighQualityBicubic;

    grPhoto.DrawImage(imgPhoto,
        new Rectangle(destX, destY, destWidth, destHeight),
        new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
        GraphicsUnit.Pixel);

    grPhoto.Dispose();
    return bmPhoto;
}

Hope this helps.

凉宸 2024-08-15 22:27:02

查看 Image.FromStream()

http://msdn.microsoft 的文档。 com/en-us/library/93z9ee4x.aspx

您需要在图像的生命周期内保持流打开。让第一个 MemoryStream 打开更长时间,它应该可以工作。

Look at the documentation for Image.FromStream()

http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx

You need to keep the stream open for the lifetime of the Image. Keep the first MemoryStream open longer, and it should work.

眼眸里的快感 2024-08-15 22:27:02

需要注意的一件事是 blogPhoto 和底层数据正在消失。它从哪里加载?它是从流中加载的吗?该流是否在 createSmallerImage 之前关闭?从流关闭的流加载的图像在 95% 的时间内都可以正常工作,并且只会偶尔抛出一般 GDI+ 错误。

One thing to look at is blogPhoto and the underlying data going away. Where does it get loaded from? Is it loaded from a stream? Is that stream closed before createSmallerImage? Images loaded from streams where the stream is closed work 95% of the time and only occaisonally throw a generic GDI+ error.

巴黎夜雨 2024-08-15 22:27:02

我不知道会发生什么,但也许随着 MemoryStreams 的减少,问题就会消失:

using (Image original = Image.FromStream(new MemoryStream(blogPhoto)))
{
    using (MemoryStream thumbData = new MemoryStream())
    {
        int newWidth;
        int newHeight;
        if ((original.Width <= newMaxWidth) || 
            (original.Height <= newMaxHeight))
        {
            original.Save(thumbData, ImageFormat.Jpeg);
            return thumbData.ToArray();
        }

        if (original.Width > original.Height)
        {
            newWidth = newMaxWidth;
            newHeight = (int)(((float)newWidth / 
                (float)original.Width) * (float)original.Height);
        }
        else
        {
            newHeight = newMaxHeight;
            newWidth = (int)(((float)newHeight / 
                (float)original.Height) * (float)original.Width);
        }

        //original.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero)
        //    .Save(thumbData, ImageFormat.Jpeg);
        //return thumbData.ToArray();

        using (Image thumb = new Bitmap(newWidth, newHeight))
        {
            Graphics g = Graphics.FromImage(thumb);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.DrawImage(original, 0f, 0f, (float)newWidth, (float)newHeight);
            thumb.Save(thumbData, ImageFormat.Jpeg);
        }
    }
}

I don't know what can be happening, but maybe with less MemoryStreams problem go away:

using (Image original = Image.FromStream(new MemoryStream(blogPhoto)))
{
    using (MemoryStream thumbData = new MemoryStream())
    {
        int newWidth;
        int newHeight;
        if ((original.Width <= newMaxWidth) || 
            (original.Height <= newMaxHeight))
        {
            original.Save(thumbData, ImageFormat.Jpeg);
            return thumbData.ToArray();
        }

        if (original.Width > original.Height)
        {
            newWidth = newMaxWidth;
            newHeight = (int)(((float)newWidth / 
                (float)original.Width) * (float)original.Height);
        }
        else
        {
            newHeight = newMaxHeight;
            newWidth = (int)(((float)newHeight / 
                (float)original.Height) * (float)original.Width);
        }

        //original.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero)
        //    .Save(thumbData, ImageFormat.Jpeg);
        //return thumbData.ToArray();

        using (Image thumb = new Bitmap(newWidth, newHeight))
        {
            Graphics g = Graphics.FromImage(thumb);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.DrawImage(original, 0f, 0f, (float)newWidth, (float)newHeight);
            thumb.Save(thumbData, ImageFormat.Jpeg);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文