【问题标题】:Resize and optimize Image before upload C#在上传 C# 之前调整图像大小和优化图像
【发布时间】:2023-03-23 13:23:01
【问题描述】:

我正在使用 C#、MVC5 并且我正在从我的 Web 应用程序上传图像,但我意识到我有性能问题,因为我没有优化它们,我需要修复它,这对于保持质量很重要。 您可以在下面看到报告为什么慢的结果。

我该怎么做?

我正在使用以下代码将文件保存到本地路径中。

string imgpathvalue = ConfigurationManager.AppSettings["RestaurantPath"];
 
string path = System.IO.Path.Combine(Server.MapPath(imgpathvalue));

if (!Directory.Exists(path))
 {
     Directory.CreateDirectory(path);
 }
 string pic = System.IO.Path.GetFileName(restaurantImg.FileName.Replace(" ", "_").Replace("%", "_"));
              path = System.IO.Path.Combine(Server.MapPath(imgpathvalue), pic);
                    // file is uploaded

 restaurantImg.SaveAs(path);

我尝试了下面的代码,但收到错误“GDI+ 中发生一般错误。”

  System.Drawing.Bitmap bmpPostedImage = new System.Drawing.Bitmap(restaurantImg.InputStream);
                    System.Drawing.Image objImage = ResizeImages.ScaleImage(bmpPostedImage, 81);
                    using (var ms = new MemoryStream())
                    {
                        objImage.Save(ms, objImage.RawFormat);
                        //ResizeImages.getImage(ms.ToArray());

                    }
 public static System.Drawing.Image ScaleImage(System.Drawing.Image image, int maxHeight)
        {
            var ratio = (double)maxHeight / image.Height;
            var newWidth = (int)(image.Width * ratio);
            var newHeight = (int)(image.Height * ratio);
            var newImage = new Bitmap(newWidth, newHeight);
            using (var g = Graphics.FromImage(newImage))
            {
                g.DrawImage(image, 0, 0, newWidth, newHeight);
            }
            return newImage;
        }

【问题讨论】:

  • 您不应该在 ASP.NET 中使用 System.Drawing。改用 ImageMagick 之类的库。
  • ImageMagick 调整和优化图像?你能根据我的代码分享一些代码吗?
  • 什么宽度和高度最好保持相同的质量而不是浆糊?

标签: c# image model-view-controller file-upload image-resizing


【解决方案1】:

您缺少一些用于正确调整图像大小的代码。 Appending 是一个函数,可以根据您为其提供的宽度和高度值正确调整图像大小(在本例中,如果可能,图像将调整为 120*120)。

函数调用:

ResizeImage("Path to the Image you want to resize", 
    "Path you want to save resizes copy into", 120, 120);

要进行这样的函数调用,我们需要编写函数。它从sourceImagePath 获取图像并创建一个新的位图。

然后它会计算调整图像大小的因素,并根据宽度或高度是否更大进行相应调整。

完成后,我们从sourceImagePath 创建一个新的位图并调整它的大小。最后我们还需要处理sourceImagedestImage,我们还需要处理我们用于不同质量设置的图形元素g。

调整大小功能:

private void ResizeImage(string sourceImagePath, string destImagePath, 
    int wishImageWidth, int wishImageHeight)
{
    Bitmap sourceImage = new Bitmap(sourceImagePath);
    Bitmap destImage = null;
    Graphics g = null;
    int destImageWidth = 0;
    int destImageHeight = 0;

    // Calculate factor of image
    double faktor = (double) sourceImage.Width / (double) sourceImage.Height;

    if (faktor >= 1.0) // Landscape
    {
        destImageWidth = wishImageWidth;
        destImageHeight = (int) (destImageWidth / faktor);
    }
    else // Port
    {
        destImageHeight = wishImageHeight;
        destImageWidth = (int) (destImageHeight * faktor);
    }

    try
    {
        destImage = new Bitmap(sourceImage, destImageWidth, destImageHeight);
        g = Graphics.FromImage(destImage);
        g.InterpolationMode = 
            System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        g.SmoothingMode = 
            System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
        g.PixelOffsetMode = 
            System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; 
        g.CompositingQuality = 
            System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        g.DrawImage(sourceImage, 0, 0, destImageWidth, destImageHeight);
        // Making sure that the file doesn't already exists.
        if (File.Exists(destImagePath)) {
            // If it does delete the old version.
            File.Delete(destImagePath);
        }
        destImage.Save(destImagePath);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("*** ERROR-Terror: " + ex.Message)
    }
    finally
    {
        if (g != null) { g.Dispose(); g = null; }
        if (destImage != null) { destImage.Dispose(); destImage = null; }
    }

    sourceImage.Dispose();
    sourceImage = null;
}

【讨论】:

  • 此代码不保证 BitmapGraphics 对象将沿所有代码路径进行处理。您应该使用using() 块,这里不需要catch,使用Console.WriteLine 在ASP.NET 中是一个NOOP。
  • 我收到一个错误 GDI+ 中的 catch 部分发生一般错误,因为在同一路径上已经存在同名错误。我可以替换它还是应该先删除它?
  • 如果存在 File.Exists,您可以在创建新图像之前使用 File.Delete 删除图像
  • @marios 我添加了代码以确保即使在同一目录中已经存在同名的文件,您也可以保存文件。
猜你喜欢
  • 1970-01-01
  • 2011-04-16
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多