2007/09/03(Mon) 15:01:53 編集(投稿者)
>■No7290 (Hongliang さん) に返信
> Image クラスは、ビットマップイメージとベクタイメージを統一的に扱うためのクラスです。
> ですので、当然ながら LockBits メソッドを持っていません。ビットマップイメージじゃないと意味がないメソッドですからね。
> ですから、Image から直接派生して LockBits で操作するクラスってのは、設計がおかしいと言うことになります。
>
> でもそういうのは派生させるよりユーティリティクラス的に外部から操作した方がいいと思うなぁ。
回答ありがとうございます。
実は、ttp://junki.lix.jp/csgr/005ColorDataAccess3.htmのサイトを参考に
/// <summary>高速ビットマップ機能(暫定)</summary>
public class ExBitmap : IDisposable
{
private bool _flagDispose = false;
private Bitmap _Bitmap;
private BitmapData _BitmapData;
private IntPtr _Pointer;
private int _Stride;
private int _DataSize;
private byte[] _ColorData;
public Bitmap GetBitmap() { return _Bitmap; }
public ExBitmap(Bitmap bitmap) { _Bitmap = bitmap; Main(); }
public ExBitmap(int width, int height) { _Bitmap = new Bitmap(width, height); Main(); }
// TODO: これだと、Aチャンネルにアクセスできないらしい...? public ExBitmap(Image image) { _Bitmap =new Bitmap(image); }
private void Main()
{
_BitmapData = _Bitmap.LockBits(new Rectangle(0, 0, _Bitmap.Width, _Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
_Pointer = _BitmapData.Scan0;
_Stride = _BitmapData.Stride;
_DataSize = _Stride * _Bitmap.Height;
_ColorData = new byte[_DataSize];
// ARGBデータのメモリコピーを可能にします。
System.Runtime.InteropServices.Marshal.Copy(_Pointer, _ColorData, 0, _DataSize);
}
public Color GetPixel(int x, int y)
{
int ix = (_Stride * y) + (x * 4);
byte A = _ColorData[ix + 3];
byte R = _ColorData[ix + 2];
byte G = _ColorData[ix + 1];
byte B = _ColorData[ix + 0];
return Color.FromArgb(A, R, G, B);
}
public void SetPixel(int x, int y, Color col)
{
int ix = (_Stride * y) + (x * 4);
_ColorData[ix + 3] = col.A;
_ColorData[ix + 2] = col.R;
_ColorData[ix + 1] = col.G;
_ColorData[ix + 0] = col.B;
}
protected virtual void Dispose(bool flag)
{
if (!_flagDispose)
{
if (flag)
{
// ARGBデータの転送を行います。
System.Runtime.InteropServices.Marshal.Copy(_ColorData, 0, _Pointer, _DataSize);
_Bitmap.UnlockBits(_BitmapData);
}
this._flagDispose = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~ExBitmap()
{
Dispose(false);
}
}
を実装してみました。
これで、かなりの速度で画像データにアクセスできます。
しかし、SetPixel()でアクセスした画像を得るには、
GetBitmap()を通さないと画像データが受け取れないので、
Imageクラスから派生したBitmapオブジェクト的な感じの
実装をしたいと思い質問させていただきました。
上記のような実装ってできないのでしょうか?