2016-08-19 9 views
-1

ユーザがアップロードした大きな画像のサイズを変更しようとしていて、サムネイルサイズに縮小しようとしています。大きな画像のサイズを変更すると、Image.FromStream()を呼び出すときに「パラメータが無効です」がスローされます

私は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); 

他の小さいサイズの画像は、この正確なコードを使用してエラーなしで動作します。大きな画像をサポートするためにこのコードを変更する方法はありますか?

更新:追加されました@ハンスアンパッサンにより示唆されるように使用するには、マティアス・キケロと@Plutonix

+0

「imageStream」には有効な画像が含まれていますか? –

+0

あなたがリンクした画像をダウンロードしたところ、 'Image.FromStream'をちょうど良いものと呼ぶことができました。 –

+1

あなたはDispose()を呼び出すのにうんざりしています。 **サムネイルや画像の変数には常に* **使用する必要がありますので、*使用*ステートメントを使用して、きれいで例外的に安全であるようにしてください。使い捨ての使い方は簡単で、長時間働くことができます。しかし、ImageクラスとBitmapクラスでは、管理されていないメモリがたくさん必要になることがあり、**非常に**許しません。 –

答えて

-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; 
      } 
     } 
    } 
関連する問題