0

OutOfMemoryExceptionOOMを特徴とする多くの質問に見られる画像のサイズ変更の典型的な例を使用しているため、画像のサイズ変更に完全に固執しています。

Nuget にある DynamicImage も試してみましたが、これもOutOfMemoryException.

メモリにロードせずに、C#で画像の品質/サイズを縮小する方法を誰か教えてもらえますか?

編集:もしあれば、これと同等のc#が欲しいですか?

編集:古いサーバーで実行されているライブサイトで OutOfMemoryExceptions を回避できないため、サイズ変更の一般的な方法をあきらめます。

さらに編集:私のサーバーのOSは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例外を回避するための解決策を探しています。画像をメモリにロードせずにサイズを縮小するという考えがありましたが、私を助けることができる代替のアイデアをいただければ幸いです。

4

3 に答える 3

1

コマンド ラインまたは.NET バインディングからImageMagickを試すことができます。ImageMagick には、ファイルの読み取り中にサイズを変更するオプションがいくつかあります。これにより、メモリ消費が削減されるはずです。

于 2013-01-20T18:31:31.370 に答える
0

画像を適切に処理していないレガシーコードを継承したことについては言及しませんでした。修正してから関連性があるとは思わなかったためです。奇妙なことに、WebサイトとAppPoolを再起動した後、OutOfMemoryExcepitonを取得せずに画像を再度アップロードできました。画像を適切に処理するようにコードを変更し、それ以来いくつかのデプロイを行ったため、なぜこれが発生したのか理解するのに苦労しています。したがって、処理されていない画像をメモリからクリアすることを期待しますか?画像のサイズ変更とアップロードのコードはすべて静的クラスにあり、GC.collect()は静的変数では機能しないと思いますか?

私の理論では、未処理の画像はメモリに蓄積され、サイトに再ポリーシングしても残っています。これは、アプリプールを再起動した後にコードが再び機能し始めてから到達できる唯一の結論です。

私は私の質問を削除しますが、それは今答えられました。誰かがここで何が起こっているのかを説明するのを手伝ってくれるなら、答えを再割り当てしてください。

于 2013-01-22T18:08:19.733 に答える
0

使用している「イメージ」がサポートされていない形式であるか、破損している可能性があります。

于 2013-01-20T18:26:15.640 に答える