2

Web サイトにアップロードされた画像を縮小およびトリミングするための簡単な PhotoEditor ヘルパー クラスを作成しました。すべてが機能していますが、画像をファイルに保存すると、満足のいく品質が得られません。以下で調整できるさまざまな設定を読みましたが、サイズ変更のセットアップは同じです。トリミングは同じです。

    public Image ResizeImage(Image imgToResize, Size size)
    {
        int sourceWidth = imgToResize.Width;
        int sourceHeight = imgToResize.Height;

        float nPercentW = (size.Width/(float) sourceWidth);
        float nPercentH = (size.Height/(float) sourceHeight);

        float nPercent = nPercentH < nPercentW ? nPercentH : nPercentW;

        var destWidth = (int) (sourceWidth*nPercent);
        var destHeight = (int) (sourceHeight*nPercent);

        var src = imgToResize;

        using (var dst = new Bitmap(destWidth, destHeight, imgToResize.PixelFormat))
        {
            dst.SetResolution(imgToResize.HorizontalResolution, imgToResize.VerticalResolution);

            using (var g = Graphics.FromImage(dst))
            {
                var mime = GetMimeType(imgToResize);
                ImageFormat format;
                if (mime == "image/gif" || mime == "image/png")
                {
                    //convert all gif to png, better resize quality
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.DrawImage(src, 0, 0, dst.Width, dst.Height);
                    format = ImageFormat.Png;
                }
                else
                {
                    //jpeg
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    format = ImageFormat.Jpeg;
                }
                g.DrawImage(src, 0, 0, dst.Width, dst.Height);

                // At this point the new bitmap has no MimeType
                // Need to output to memory stream
                var m = new MemoryStream();
                dst.Save(m, format);

                var img = Image.FromStream(m);

                return img;
            }
        }
    }

ご覧のとおり、補間、スムージングなどの推奨設定を使用しています。また、品質 100 で jpeg を保存しています。

結果として得られる画像には、元のサイズのわずか 75% にサイズ変更しても、顕著なぼやけとアーティファクトがあります。いろいろ調べましたが、これがおすすめです。サイズを変更する簡単な方法を見つけたので、試してみることにしました。

Bitmap NewImg = new Bitmap(original, new Size(387,257));
editor.SaveImage(@"C:\simpleResize.jpg", NewImg, ImageFormat.Jpeg);

驚くべきことに、メモリ フットプリントが 30% ほど大きくなりますが、これによりはるかに優れた画像が生成されます。

私の質問は、違いは何ですか、サイズ変更ルーチンで欠落している設定は、醜い結果の原因となる可能性があるということです。サイズ変更ルーチンを取得して、単純なサイズ変更とまったく同じ結果を生成したいと考えています。

あなたの助けに感謝します。これは、画像処理への私の最初の進出です。

編集

シンプルなリサイズ (82KB)

シンプル http://img189.imageshack.us/img189/2137/simpleresize.jpg

マイリサイズ (55KB)

複雑 http://img12.imageshack.us/img12/4023/complexresize.jpg

4

2 に答える 2

4

次のサンプル コード スニペットを見つけました (ソースを忘れてしまい申し訳ありません)。

// Create parameters
EncoderParameters params = new EncoderParameters (1);

// Set quality (100)
params.Param[0] = new EncoderParameter(Encoder.Quality, 100);

// Create encoder info
ImageCodecInfo codec = null;
foreach (ImageCodecInfo codectemp in ImageCodecInfo.GetImageDecoders())
{
    if (codectemp.MimeType == "image/jpeg")
    {
        codec = codectemp;
        break;
    }
}

// Check
if (codec == null)
    throw new Exception("Codec not found for image/jpeg");

// Save
image.Save(filename, codec, params);
于 2009-07-26T22:11:13.093 に答える
2

私が最初に考えたのは、.NET の jpeg エンコーダーは最高品質の設定でもクロマ サブサンプリングを使用するため、色情報は半分の解像度で保存されるということでした。私が知る限り、設定はハードコーディングされています。しかし、それでは 2 番目の例でより良い品質が得られる理由を説明できません。おそらく2番目にアンチエイリアシングを使用しなかった場合を除き、よりシャープな(しかし低品質の)画像を提供し、アーティファクトは見過ごされました.

編集: dst.Save(m, format); あなたの問題のように見えます。そこで、デフォルトの品質(100%ではない)でjpegとしてエンコードし、すぐにデコードして画像に戻します。dst は既に Image (Bitmap クラスは Image から継承) であるため、そのまま返すことができます。

于 2009-07-21T22:34:35.013 に答える