【C#】Bitmapの解像度(DPI)の取得設定

画像ファイルのプロパティをエクスプローラーで表示すると、下図のように水平方向の解像度、垂直方向の解像度が表示されますが、ほとんどの場合、Windowsでは96dpiと表示される場合が多いのですが、この解像度の値をC#で取得、設定(変更)してみたいと思います。

 

 

解像度を設定するにはBitmapクラスのSetResolutionメソッドを用いて、以下のように設定します。

var bmp = new Bitmap("Mandrill.bmp");
bmp.SetResolution(400, 400);

解像度を取得するにはGetResolutionではなくて、HorizontalResolutionプロパティVerticalResolutionプロパティが用意されています。

 

(コード例)

Console.WriteLine(String.Format("水平分解能 = {0}, 垂直分解能 = {1}", bmp.HorizontalResolution, bmp.VerticalResolution));

(実行結果)

 

試しに下記のようなコードで、Bitmap,Jpeg,Png,Tiffファイルで解像度の設定が有効になっているか?確認してみましたが、どれも設定されていました。

var bmp = new Bitmap("Mandrill.bmp");
bmp.Save("Mandrill400.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
bmp.Save("Mandrill400.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Save("Mandrill400.png", System.Drawing.Imaging.ImageFormat.Png);
bmp.Save("Mandrill400.tif", System.Drawing.Imaging.ImageFormat.Tiff);

ただし、Bitmapファイル(*.bmp)だけはファイルのプロパティで解像度が表示されなかったので、エクスプローラーで表示項目を増やして解像度を確認しました。

 

 

画像処理のためのC#テクニックへ戻る

【OpenCV】IplImageから.NETのBitmapへ変換

OpenCVのプログラムを作っていると、OpenCV用のGUI(highgui)はかなり物足りなく、ウィンドウや表示まわりは.NETに任せたいので、OpenCVのIplImageから.NET(C++/CLI)のBitmapへ変換すると、簡単にウィンドウプログラムを作成する事が可能となります。

 

変換部分のサンプルプログラムは以下の通りです。

// IplImage の確保
IplImage *src_img = cvLoadImage("c:\\Sample.bmp");
//  IplImageからBitmapの確保
Bitmap^ bmp = gcnew Bitmap(src_img->width, src_img->height, src_img->widthStep,
      System::Drawing::Imaging::PixelFormat::Format24bppRgb, (IntPtr)src_img->imageData);

ただし、PixelFormatはIplImageで確保した画像データのdepthおよびnChannelsに合わせて設定して下さい。

 

PixelFormat depth nChannels
Format8bppIndexed 8 1
Format24bppRgb 8 3

 

他の組合せも考えられますが、.NETやOpenCVの関数が対応していないものが多いので、実質的に、この2つの組合せになると思います。
モノクロ8Bit画像(Format8bppIndexed)の場合は、別途、カラーパレットを設定する必要があります。
カラーパレットの設定については、8Bitモノクロのカラーパレット設定方法のページを参照願います。

 

ここで作成したBitmapをPictureBoxに表示する場合、

 

pictureBox1->Image = bmp;

 

とすると

 

‘System.AccessViolationException’ のハンドルされていない例外が System.Drawing.dll で発生しました。
追加情報: 保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。

 

というエラーメッセージが出てしまうので、DrawImageを使って

 

g->DrawImage(bmp, 0, 0, src_img->width, src_img->height);

 

というようにして、ピクチャボックスへ描画します。

 

ちなみに今回はIplImageからBitmapクラスへ変換する方法を紹介しましたが、BitmapクラスからIplImageへ変換する場合はBitmapクラスのポインタがガーベージコレクションにより移動してしまう可能性があるので、BitmapのポインタをLock~Unlockで取得し、IplImageのimageDataへコピーすればよいと思います。

 

また、OpenCV2.0からは画像データにC++用のcv::Matがありますが、cv::Matでは画像データのメモリの幅が4の倍数に調整されていないので、画像の幅が4の倍数でない場合はcv::Matと.NETのBitmapとではメモリのサイズが異なるため、そのままcv::MatのポインタをBitmapへ渡す事ができません。
そのため、cv::MatからBitmapへ変換する場合はcv::MatそのものをIplImageを確保してからcv:Matへ変換するか、画像の1行ごとにデータをコピーするなどの工夫が必要となります。

 

 

OpenCVへ戻る