繁体   English   中英

降低图像质量/尺寸而不加载到内存中?

[英]Reduce image quality/size without loading into memory?

我完全迷恋于图像调整大小,因为我正在使用图像调整大小的典型示例获取OutOfMemoryException ,这些示例可以在许多带有OOM的问题中找到。

我什至尝试过在Nuget上可以找到的DynamicImage,这也引发了OutOfMemoryException

谁能告诉我如何减少C#中图像的质量/大小而不将其加载到内存中?

编辑:我想要与此等效的C#,如果有的话?

编辑:我放弃了通常的调整大小方法,因为我无法避免在运行于旧服务器上的实时站点上出现OutOfMemoryExceptions。

进一步的编辑:我的服务器的操作系统是Microsoft Server 2003 Standard Edition

我可以发布代码示例,但是我试图找到一种解决OutOfMemoryExceptions的方法。

public static void ResizeImage(string imagePath, int imageWidth, int imageHeight, bool upscaleImage) {
      using (Image image = Image.FromFile(imagePath, false)) {
        int width = image.Width;
        int height = image.Height;
        if (width > imageWidth || height > imageHeight || upscaleImage) {

          image.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);
          image.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);

          float ratio = 0;
          if (width > height) {
            ratio = (float)width / (float)height;
            width = imageWidth;
            height = Convert.ToInt32(Math.Round((float)width / ratio));
          }
          else {
            ratio = (float)height / (float)width;
            height = imageHeight;
            width = Convert.ToInt32(Math.Round((float)height / ratio));
          }

          using (Bitmap bitmap = new Bitmap(width, height)) {
            bitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution);
            using (Graphics graphic = Graphics.FromImage(bitmap)) {

              graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
              graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
              graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
              graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
              graphic.DrawImage(image, 0, 0, width, height);

              string extension = ".jpg"; // Path.GetExtension(originalFilePath);

              using (EncoderParameters encoderParameters = new EncoderParameters(1)) {
                encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
                using (MemoryStream imageMemoryStream = new MemoryStream()) {
                  bitmap.Save(imageMemoryStream, GetImageCodec(extension), encoderParameters);
                  using (Image result = Image.FromStream(imageMemoryStream, true, false)) {
                    string newFullPathName = //path;
                    result.Save(newFullPathName);
                  }
                }
              }
            }
          }
        }
      }
        }

我也尝试了这段代码,因为我希望GetThumbnailImage可以为我降低图片质量/大小,但这也会引发OOM异常:

viewModel.File.SaveAs(path);
        Image image = Image.FromFile(path);
        Image thumbnail = image.GetThumbnailImage(600, 600, null, new IntPtr());
        image.Dispose();
        File.Delete(path);
        thumbnail.Save(path);
        thumbnail.Dispose();

同样,我的两个代码示例都在本地计算机上为我工作,因此,我没有试图在代码中查找错误/修复,因为它们应该没问题。 我正在寻找避免OOM异常的任何解决方案,我的想法是在不将图像加载到内存的情况下以某种方式减小fize的大小,但是任何可以帮助我的替代方法都将不胜感激。

您可以尝试通过命令行.NET绑定使用ImageMagick ImageMagick有一些选项可以在读取文件时调整大小,这可以减少内存消耗。

您使用的“图像”可能不是受支持的格式或已损坏。

我没有提到我继承了无法正确处理图像的遗留代码,因为自修复以来,我认为它并不重要。 奇怪的是,在重新启动网站和AppPool之后,我能够再次上传图片而没有得到OutOfMemoryExcepiton。 我一直在努力理解为什么会发生这种情况,因为我更改了代码以正确处理图像,并且此后进行了多次部署,因此我希望从内存中清除所有未处理的图像吗? 图片调整大小和上传的所有代码都在静态类中,我相信GC.collect()在静态变量上不起作用吗?

我的理论是,即使我重新分配到站点,未处理的图像也会在内存中累积,并且仍然存在,因为这是自从代码在重新启动应用程序池后重新开始工作以来我唯一能得出的结论。

我将删除我的问题,但现在已经回答了,如果有人可以帮助解释这里的情况,很高兴重新分配答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM