#topicpath
#contents
* C# [#lc99d52c]
C#でピクセル配列の描画をやってみます。([[関連日記>http://gir-lab.spaces.live.com/blog/cns!63A4C32EDA5CF2F7!420.entry]])
- クリックすると正方形が描画されます。
#ref(PixelDrawing-20061030.png,nolink)
#ref(PixelDrawing-20061030.zip)
#include(:VCS2005Exp,notitle)
** 実装 [#sd158e23]
Win32APIのSetDIBitsToDevice()を利用しています。
[DllImport("GDI32.DLL")]
internal static extern int SetDIBitsToDevice(
IntPtr hdc, // デバイスコンテキストのハンドル
int XDest, // 転送先長方形の左上隅の x 座標
int YDest, // 転送先長方形の左上隅の y 座標
int dwWidth, // 転送元長方形の幅
int dwHeight, // 転送元長方形の高さ
int XSrc, // 転送元長方形の左下隅の x 座標
int YSrc, // 転送元長方形の左下隅の y 座標
int uStartScan, // 配列内の最初の走査行
int cScanLines, // 走査行の数
int[] lpvBits, // DIB ビットからなる配列
ref BITMAPINFO lpbmi, // ビットマップ情報
int fuColorUse // RGB 値またはパレットインデックス
);
使用しているBITMAPINFO構造体の定義です。
[StructLayout(LayoutKind.Sequential)]
internal struct BITMAPINFOHEADER
{
public int biSize;
public int biWidth;
public int biHeight;
public short biPlanes;
public short biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int biClrImportant;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BITMAPINFO
{
public BITMAPINFOHEADER bmiHeader;
}
*** 使用例 [#sefea806]
int w = pictureBox1.Width, h = pictureBox1.Height;
Graphics g = pictureBox1.CreateGraphics();
IntPtr hdc = g.GetHdc();
int[] buffer = new int[w * h];
BITMAPINFO bmpInfo = new BITMAPINFO();
bmpInfo.bmiHeader.biSize = Marshal.SizeOf(bmpInfo);
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biWidth = w;
bmpInfo.bmiHeader.biHeight = -h;
SetDIBitsToDevice(hdc, x, y, w, h, 0, 0, 0, h, buf, ref bmpInfo, 0);
g.ReleaseHdc(hdc);
g.Dispose();
** PixelBuffer [#r783142f]
- int[]のバッファとSetDIBitsToDevice()による描画をラッピングしたクラスです。
- このクラスの実装を差し替えることで別々の環境に対応させるのが目標です。
- 描画は点を打つだけの機能を提供します。
*** 使用例 [#u27200c4]
色は"αRGB"で指定しますが、SetDIBitsToDevice()ではα値は無視されます。
int w = pictureBox1.Width, h = pictureBox1.Height;
Graphics g = pictureBox1.CreateGraphics();
PixelBuffer pb = new PixelBuffer(w, h);
pb.setPixel(32, 32, 0xffff0000); // 赤
pb.setPixel(64, 64, 0xff00ff00); // 緑
pb.setPixel(64, 64, 0xff0000ff); // 青
pb.draw(g);
g.Dispose();
** PixelGraphics [#mf572fed]
PixelBufferに対して描画するクラスです。
- 環境依存部分をPixelBufferに押し込めるため分離しました。
- PixelGraphicsはPixelBufferに対して地道にsetPixel()するだけのクラスなので、PixelBufferだけを移植すればPixelGraphicsは自動的に対応できるはず、というのが狙いです。
*** 使用例 [#p1fa2be6]
int w = pictureBox1.Width, h = pictureBox1.Height;
Graphics g = pictureBox1.CreateGraphics();
PixelBuffer pb = new PixelBuffer(w, h);
PixelGraphics pg = new PixelGraphics(pb);
pg.fillRectangle(0xffff0000, 10, 10, 20, 20);
pg.drawRectangle(0xff0000ff, 20, 20, 20, 20);
pb.draw(g);
g.Dispose();
** コメント [#ye6a380f]
#comment(below)
//#comment(below)