MBu*_*lli 5 c# graphics gdi+ bitmap bitblt
我尝试将图形对象的内容复制到位图.我正在使用此代码
public static class GraphicsBitmapConverter
{
[DllImport("gdi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
public static Bitmap GraphicsToBitmap(Graphics g, Rectangle bounds)
{
Bitmap bmp = new Bitmap(bounds.Width, bounds.Height);
using (Graphics bmpGrf = Graphics.FromImage(bmp))
{
IntPtr hdc1 = g.GetHdc();
IntPtr hdc2 = bmpGrf.GetHdc();
BitBlt(hdc2, 0, 0, bmp.Width, bmp.Height, hdc1, 0, 0, TernaryRasterOperations.SRCCOPY);
g.ReleaseHdc(hdc1);
bmpGrf.ReleaseHdc(hdc2);
}
return bmp;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我像这样使用这种方法
Graphics g = button1.CreateGraphics();
var bmp = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds));
Run Code Online (Sandbox Code Playgroud)
位图包含内容.但是如果我在调用方法之前绘制图形对象,则位图是空白的:
using (Bitmap bmp = new Bitmap(100, 100))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.FillRectangle(Brushes.Red, 10, 10, 50, 50);
g.FillRectangle(Brushes.Blue, 20, 20, 50, 50);
g.FillRectangle(Brushes.Green, 0, 0, bmp.Width, bmp.Height);
var bmp2 = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds));
}
}
Run Code Online (Sandbox Code Playgroud)
为什么它适用于第一种情况而不适用于后者?
小智 1
据我了解
Graphics g = Graphics.FromImage(bmp)
Run Code Online (Sandbox Code Playgroud)
创建一个用于绘制图像的 Graphics 上下文,而
Graphics g = button1.CreateGraphics();
Run Code Online (Sandbox Code Playgroud)
为已经绘制到屏幕上的控件创建一个。您可以将动态创建的位图绘制到 PictureBox 中,然后对按钮执行相同的操作,例如
using (Bitmap bmp = new Bitmap(100, 100))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.FillRectangle(Brushes.Green, 0, 0, bmp.Width, bmp.Height);
g.FillRectangle(Brushes.Red, 10, 10, 50, 50);
g.FillRectangle(Brushes.Blue, 20, 20, 50, 50);
pictureBox1.Image = bmp;
pictureBox1.Update(); // force an update before doing anything with it
Graphics g2 = pictureBox1.CreateGraphics();
var bmp2 = GraphicsBitmapConverter.GraphicsToBitmap(g2, Rectangle.Truncate(g.VisibleClipBounds));
// bmp2 now has the same contents as bmp1
pictureBox1.Image = null; // bmp is about to be Disposed so remove the reference to it
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这只是重新创建您已经拥有的位图,所以我假设您还有其他用途。