调整Image.FromStream()时调整大图像的大小会抛出“参数无效”

时间:2016-08-19 13:18:34

标签: c# system.drawing

我正在尝试调整用户上传的大图片的大小,并将其缩小为缩略图大小。

read that memory issues can cause problems with very large files,因为它需要连续的记忆,但是my test image is only 5.78MB

我正在使用的代码如下:

public static byte[] GetThumbnailImage(Stream imageStream, ImageFormat format, int thumbnailWidth)
{
    using (var thumbnailStream = new MemoryStream())
    {
        imageStream.Position = 0;
        using (var image = Image.FromStream(imageStream))
        {
            var thumbnailSize = GetThumbnailSize(image, thumbnailWidth);
            using (var thumbnail = image.GetThumbnailImage(
                    thumbnailSize.Width,
                    thumbnailSize.Height,
                    null,
                    IntPtr.Zero))
            {
                thumbnail.Save(thumbnailStream, format);
                return thumbnailStream.ToArray();
            }
        }
    }
}

它被称为这样:

var thumbnailBytes = ImageHelper.GetThumbnailImage(imageStream, ImageFormat.Jpeg, 150);

使用此确切代码,其他较小尺寸的图像可以正常工作而没有任何错误。有什么办法可以改变这段代码来支持更大的图像吗?

更新:按照@ Hans-Passant,@ Matias-Cicero和@Plutonix

的建议添加

1 个答案:

答案 0 :(得分:-1)

我过去遇到过类似的问题,我认为这是由图像的大小引起的,等于0 ......

我解决了使用此类的LoadImage方法。

您可以调整它以在此调用之前加载图像: var thumbnailSize = GetThumbnailSize(image,thumbnailWidth);

    public static class ImageLoader
    {
        // This isn’t going to help much – you’ll run out of memory anyway on very large images – but if you are keeping several in memory it might …
        public const int MaximumImageDimension = 10000;

        /// 
        /// Method to safely load an image from a file without leaving the file open, 
        /// also gets the size down to a manageable size in the case of HUGE images
        /// 
        /// An Image – don’t forget to dispose of it later
        public static Image LoadImage(string filePath)
        {
            try
            {
                FileInfo fi = new FileInfo(filePath);

                if (!fi.Exists) throw new FileNotFoundException("File not found.");
                if (fi.Length == 0) throw new FileNotFoundException("File zero lenght");

                // Image.FromFile is known to leave files open, so we use a stream instead to read it
                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    if (!fs.CanRead) throw new FileLoadException("Can't read the file stream");

                    if (fs.Length == 0) throw new FileLoadException("File stream zero lenght");

                    using (Image original = Image.FromStream(fs))
                    {
                        // Make a copy of the file in memory, then release the one GDI+ gave us
                        // thus ensuring that all file handles are closed properly (which GDI+ doesn’t do for us in a timely fashion)
                        int width = original.Width;
                        int height = original.Height;
                        if (width == 0)
                            throw new DataException("Bad image dimension width=0");
                        if (height == 0) throw new DataException("Bad image dimension height=0");

                        // Now shrink it to Max size to control memory consumption
                        if (width > MaximumImageDimension)
                        {
                            height = height * MaximumImageDimension / width;
                            width = MaximumImageDimension;
                        }
                        if (height > MaximumImageDimension)
                        {
                            width = width * MaximumImageDimension / height;
                            height = MaximumImageDimension;
                        }

                        Bitmap copy = new Bitmap(width, height);
                        using (Graphics graphics = Graphics.FromImage(copy))
                        {
                            graphics.DrawImage(original, 0, 0, copy.Width, copy.Height);
                        }
                        return copy;
                    }
                }
            }
            catch (Exception ex)
            {
                ex.Data.Add("File", filePath);
                throw;
            }
        }
    }