5

多くの人が独自の画像変換技術をコーディングしようとしているのを見てきました。多くの場合、非常に複雑に見え、最終的に GDI+ 関数呼び出しを使用し、画像のビットを操作することになります。これは、画像を保存するときの .NET の画像変換呼び出しの単純さに何か欠けているのではないかと思いました。ここに私が持っているコードがあります:

Bitmap tempBmp = new Bitmap("c:\temp\img.jpg");
Bitmap bmp = new Bitmap(tempBmp, 800, 600);
bmp.Save(c:\temp\img.bmp, //extension depends on format
    ImageFormat.Bmp) //These are all the ImageFormats I allow conversion to within the program.  Ignore the syntax for a second ;) 
    ImageFormat.Gif) //or 
    ImageFormat.Jpeg) //or
    ImageFormat.Png) //or
    ImageFormat.Tiff) //or
    ImageFormat.Wmf) //or
    ImageFormat.Bmp)//or
    );

これが、画像変換で行っているすべてです。画像を保存する場所を設定し、それを ImageFormat タイプに渡すだけです。できる限りテストしましたが、この単純な形式変換で何か不足しているのか、それともこれで十分なのか疑問に思っています。

4

3 に答える 3

5

System.Drawing.ImagingJPEGコーデックを渡し、品質のエンコーダパラメータを設定すると、画像圧縮をさらに制御できます。これは、基本的に保持率です。

"image/jpeg"これは、JPEGコーデックを取得するためにパラメーターで使用する関数です。(これは圧縮自体とは関係ありませんが、Image.Save受け入れるオーバーロードは代わりにEncoderParametersrequireを必要とします。)ImageCodecInfoImageFormat

//  assumes an encoder for "image/jpeg" will be available.
public static ImageCodecInfo GetCodec( string mimeType )
{ 
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); 

    for( int i = 0;  i < encoders.Length;  i++ )
        if( encoders[i].MimeType == mimeType )
            return encoders[i];

    return null; 
}

次に、画像を保存する前にエンコーダパラメータを設定できます。

EncoderParameters ep = new EncoderParameters(2);
ep.Param[0] = new EncoderParameter( Encoder.Quality,    percentRetention ); // 1-100
ep.Param[1] = new EncoderParameter( Encoder.ColorDepth, colorDepth ); // e.g. 24L

(他のエンコーダパラメータがあります—ドキュメントを参照してください。

だから、それをすべてまとめると、あなたは言うことができます

image.Save( outFile, GetCodec("image/jpeg"), ep );

(コーデックとパラメーターは何度も使用されるため、静的な値で保存しますが、ここでは例を簡略化したいと思います。)

お役に立てれば!

編集:画像を拡大縮小する場合は、品質もある程度制御できます。はい、それは非常に「ブラックボックス」ですが、うまく機能していることがわかりました。これが「good&slow」設定です(DrawImageを呼び出す前に設定する必要がありますが、「quick&dirty」バージョンを検索できます。

// good & slow
graphics.SmoothingMode      = SmoothingMode.HighQuality;
graphics.InterpolationMode  = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode    = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
于 2010-04-20T05:05:16.730 に答える
0

あなたがしていることはうまくいくでしょうが、これまでで最も効率的ではなく、最も経済的なファイルサイズを生み出しません。

イメージングを扱うときに複雑なGDIコードが表示される理由は、デフォルトのフリーサイズの方法を使用することと、最も控えめな程度の微調整を使用することの間に合理的な中間点がないためです。

.net <-> gdi相互運用機能は、あいまいなバグがたくさんある黒魔術に隣接しています。幸いなことに、グーグルはこの地雷原をナビゲートするために必要なすべてを持っています。

(私は悲惨な絵を描きましたか?;-))

真剣に、しかし、あなたはgdi相互運用でかなりうまくいくことができます、しかしそれは決して明白な仕事ではありません。あなたが研究をして、ねじれを解決するために時間をかけることをいとわないなら、あなたはいくつかの良いコードで終わることができます。

それ以外の場合は、これのほとんどを実行するイメージングライブラリを見つけてください。

于 2010-04-20T05:04:26.420 に答える
0

imageformatを渡すことにより、.NETはImageFormatに関連付けられた圧縮を実行すると思います。

ただし、グラフィック圧縮に関しては、それだけではありません(例として、Photoshopまたはグラフィックプログラムの名前を付けて保存ダイアログを参照してください)。

たとえば、JPEGは単なる標準です...そして、多くのWebグラフィックでは、目立った品質の低下なしに、ぼやけたり、より多くの色を取り除いたりすることで、サイズを縮小することができます。

どのテクニックを使用するか、または標準で問題がないかどうかはあなた次第です。

于 2010-04-20T04:51:51.287 に答える