C# 将图形内容复制到位图
我尝试将图形对象的内容复制到位图。我正在使用这个代码C# 将图形内容复制到位图,c#,graphics,bitmap,gdi+,bitblt,C#,Graphics,Bitmap,Gdi+,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 nWidt
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;
}
}
如果我用这样的方法
Graphics g = button1.CreateGraphics();
var bmp = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds));
位图包含内容。但如果在调用methodes之前绘制图形对象,位图将为空:
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));
}
}
为什么它在第一种情况下有效而在后一种情况下无效?据我所知
Graphics g = Graphics.FromImage(bmp)
创建用于绘制到图像中的图形上下文,而
Graphics g = button1.CreateGraphics();
为已绘制到屏幕的控件创建一个。您可以将动态创建的位图绘制到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
}
}
当然,这只是重新创建了一个位图,你已经有了,所以我想你还有其他用途。你有没有尝试刷新你的图形
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);
g.Flush(); // !!
var bmp2 = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds));
}
}
你干得很辛苦。显然,由于相同的代码在不同的调用中成功和失败,因此图形使用不同的临时空间来存储信息,直到使用CreateGraphics完成请求-否则在这两种情况下都应该读取 试用
gr.Save();
对于图形,这可能会在创建之前起作用
但是,当我想进行绘图时,我只需使用以下方法克隆图形图像:
public void CopyBackgroundLayer(ref Bitmap bitmap)
{
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
bitmap = new Bitmap(buffer.Clone(rect, Primary.BackGround.PixelFormat));
}
因此,同时我向图形对象添加内容,我称之为克隆图形对象绘制的图像(示例中为缓冲区),以便在添加更多内容之前将位图添加到任意点。是否检查BitBlt()的返回值?也许它失败了,可能会导致线索。代码不完整