私はこのコードを使用して画面をキャプチャしています:
public Bitmap CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Bitmap img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}
次に、ビットマップを256色(8ビット)に変換します。このコードを試しましたが、インデックス付きのビットマップ形式から画像を作成できないというエラーが発生しました。
Bitmap img8bit = new Bitmap(img.Width,img.Height,
System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
Graphics g = Graphics.FromImage(img8bit);
g.DrawImage(img,new Point(0,0));
異なるフォーマット間でビットマップを変換するいくつかの例を見ましたが、私の場合、画面からキャプチャしながらこれを行うための最良の方法を探しています。たとえば、最初に8ビットビットマップを作成してから画面をそれにブリットすることでうまく機能する方法がある場合は、最初に画面をキャプチャして互換性のあるビットマップに変換してから変換するよりも優先されます。キャプチャして変換する方が良い場合を除いて、とにかく変換します。
Borland Builder 6.0VCLを使用してC++で記述されたプログラムがあり、それを模倣しようとしています。その場合、VCLのTBitmapオブジェクトのピクセルフォーマットを設定するだけです。Bitmap.PixelFormatは.NETでは読み取り専用です。
更新:私の場合、元のビットマップは画面からのものであり、画面からのものではないため、画面DCを使用するGraphics.GetHalftonePaletteは問題ないはずなので、答えは、最適なパレットエントリを見つける必要がある他の使用法ほど複雑ではないと思います。 file / email / download/etcから来る可能性のあるランダムなビットマップ。DIBとGetHalftonePaletteを含む20行のコードで実行できることがあると思いますが、まだそれを見つけることができません。