繁体   English   中英

C#裁剪并调整大图像的大小

[英]C# Crop & resize large images

我得到了一些非常大的建筑图纸,有时是22466x3999,深度为24,甚至更大。 我需要能够将这些版本调整为较小的版本,并能够将图像的各个部分剪切成较小的图像。

我一直在使用以下代码来调整图像大小,我在这里找到:

       public static void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider)
        {
            System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);
            if (OnlyResizeIfWider)
            {
                if (FullsizeImage.Width <= NewWidth)
                {
                    NewWidth = FullsizeImage.Width;
                }
            }
            int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
            if (NewHeight > MaxHeight)
            {
                NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
                NewHeight = MaxHeight;
            }
            System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);
            FullsizeImage.Dispose();
            NewImage.Save(NewFile);
        }

这个代码裁剪图像:

public static MemoryStream CropToStream(string path, int x, int y, int width, int height)
        {
            if (string.IsNullOrWhiteSpace(path)) return null;
            Rectangle fromRectangle = new Rectangle(x, y, width, height);
            using (Image image = Image.FromFile(path, true))
            {
                Bitmap target = new Bitmap(fromRectangle.Width, fromRectangle.Height);
                using (Graphics g = Graphics.FromImage(target))
                {
                    Rectangle croppedImageDimentions = new Rectangle(0, 0, target.Width, target.Height);
                    g.DrawImage(image, croppedImageDimentions, fromRectangle, GraphicsUnit.Pixel);
                }
                MemoryStream stream = new MemoryStream();
                target.Save(stream, image.RawFormat);
                stream.Position = 0;
                return stream;
            }
        }

我的问题是,当我尝试调整图像大小时,我得到一个Sytem.OutOfMemoryException ,这是因为我无法将完整图像加载到FullsizeImage中。

那么我想知道的是,如何在不将整个图像加载到内存中的情况下调整图像大小?

有可能OutOfMemoryException不是因为图像的大小,而是因为你没有正确处理所有的一次性类:

  • Bitmap target
  • MemoryStream stream
  • System.Drawing.Image NewImage

没有按照他们的意愿处理。 您应该在它们周围添加using()语句。

如果您只使用一个图像确实遇到此错误,那么您应该考虑将项目切换到x64。 22466x3999图片在内存中意味着225Mb,我认为它不应该是x86的问题。 (所以先尝试处理你的对象)。

最后但同样重要的是, Magick.Net非常有效地调整大型图片的大小/裁剪。

您还可以强制.Net直接从磁盘读取映像并停止内存缓存。

采用

sourceBitmap = (Bitmap)Image.FromStream(sourceFileStream, false, false);

代替

...System.Drawing.Image.FromFile(OriginalFile);

请参阅https://stackoverflow.com/a/47424918/887092

暂无
暂无

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

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