画像ファイルを読み込む
.NET Framework を使えば、画像ファイルを読み込むだけならとても簡単。
// C#
string filename = @"C:\test\image.png";
var bitmap = new System.Drawing.Bitmap( filename );
// C++CLI
System::String^ filename = gcnew System::String( L"C:\\test\\image.png" );
System::Drawing::Bitmap^ bitmap = gcnew System::Drawing::Bitmap( filename );
Bitmapクラスでは、BMP、GIF、EXIF、JPG、PNG、TIFF が読み込める。詳しいことは
に書いてある。
対応形式がこれだけあればじゅうぶん。これ以外のファイルだったとしても、いったんペイントブラシで読んで、JPGやPNGで保存し直せばいい。
GDIで描画するなら、あとは
// C#
protected override void OnPaint( PaintEventArgs e )
{
e.Graphics.DrawImage( bitmap, 0, 0 );
}
で済むが、OpenGLで描画するならもうあと3ステップ必要。
Bitmapから色データ列を読み出す。
OpenGLの書式に合わせて並べ替える。
OpenGLに読み込ませる。
まずBitmapから色データを読み出す処理は、
// C++CLI
System::Drawing::Bitmap^ bitmap;
auto rect = System::Drawing::Rectangle( 0, 0, bitmap->Width, bitmap->Height );
Imaging::BitmapData^ bmpData = bitmap->LockBits( rect,
Imaging::ImageLockMode::ReadOnly,
Imaging::PixelFormat::Format24bppRgb );
const byte* scan0 = (const byte*)bmpData->Scan0.ToPointer();
生ポインタ scan0 が、画像の各ピクセルのRGB値が順番に並んだ配列の先頭を指している。
Bitmap は画像の左上のピクセル、その右隣、さらにその右隣、・・・という順番でデータが入っている。画像のいちばん右に到達したら0バイト~数バイトの余白があって、ひとつ下の行のいちばん左からまた順に並ぶ。
余白があるのは、画像1行分のデータ(Stride)の大きさを「きりのいい数字」にするため(4の倍数だったか8の倍数だったか、忘れてしまったが)。よくある、画像データの決まり事のようなもの。
色の並びはBGR。RGBではなくBGR。
次のOpenGLの書式に合わせて並べ替える処理は、まず OpenGLの書式を知る必要があるので別記事にする。