品質を指定してJPEGファイル保存する
特に何も考えずにデフォルト品質でビットマップを JPEG ファイルとして保存する場合は下記のようにします。
const String FILEPATH_SRC_BMP = "c:/tmp/test_src.bmp";
const String FILEPATH_DST_JPG = "c:/tmp/test_dst.jpg";
private void button2_Click( object sender, EventArgs e )
{
using ( Bitmap bmp = new Bitmap( FILEPATH_SRC_BMP ))
{
bmp.Save( FILEPATH_DST_JPG, ( ImageFormat.Jpeg ));
}
}
JPEG品質を指定して保存する場合は下記のようにします。少しめんどくさいです。
Form1 に button1 を配置して下記を実行してください。
58行目で JPEG 品質を 10% に指定しています。ここの値は 0 ~ 100 が指定できます。
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
namespace aaa
{
public partial class Form1 : Form
{
const String FILEPATH_SRC_BMP = "c:/tmp/test_src.bmp";
const String FILEPATH_DST_JPG = "c:/tmp/test_dst.jpg";
public Form1()
{
InitializeComponent();
}
// 指定のエンコーダを取得するメソッド.
private bool get_encoder( ref ImageCodecInfo want_encoder, ImageFormat format )
{
ImageCodecInfo [] arr_codecs = ImageCodecInfo.GetImageDecoders();
foreach ( ImageCodecInfo codec in arr_codecs )
{
if ( codec.FormatID == format.Guid )
{
want_encoder = codec;
return true;
}
}
want_encoder = null;
return false;
}
private void button1_Click( object sender, EventArgs e )
{
// JPEG用のエンコーダを取得する.
ImageCodecInfo enc = null;
bool ret = get_encoder( ref enc, ( ImageFormat.Jpeg ));
if ( !ret )
{
MessageBox.Show( "JPEGエンコーダが取得できませんでした." );
return; // warning.
}
// ビットマップとしてJPEGを開く.
using ( Bitmap bmp = new Bitmap( FILEPATH_SRC_BMP ))
{
// エンコーダ用のパラメータを設定する.
int quality = 10;
EncoderParameters enc_params = new EncoderParameters( 1 );
enc_params.Param[0] = new EncoderParameter(( Encoder.Quality ), quality );
// ファイルパスに関連付けたファイルストリームを生成する.
FileMode fm = FileMode.Create;
FileAccess fa = FileAccess.Write;
FileShare fs = FileShare.None;
const int BUFFER_SIZE = 4096;
FileOptions fo = FileOptions.WriteThrough;
using ( FileStream file_stream = new FileStream( FILEPATH_DST_JPG, fm, fa, fs, BUFFER_SIZE, fo ) )
{
// 開いたビットマップをエンコーダパラメータに応じて別名保存する.
bmp.Save( file_stream, enc, enc_params );
// ファイルストリームをフラッシュする.
file_stream.Flush();
}
}
try
{
// 元のファイルと、品質を変更して保存したファイルを表示する.
Process.Start( FILEPATH_SRC_BMP );
Process.Start( FILEPATH_DST_JPG );
}
catch ( Exception excp )
{
// 例外が発生したときはメッセージボックスを表示する.
MessageBox.Show( excp.Message );
}
}
}
}
上記のコードは、別名保存するファイルパスにファイルストリームを関連付けておりますが、Save の第一引数を単にファイルパスにしても同じ結果が得られます。
前者ならばディスクキャッシュの影響を排除して保存できますが、後者はディスクキャッシュの影響が生じます。
しかし巨大な JPEG ファイルでなければディスクキャッシュの影響は感じられないと思います。