Copy graphic content to bitmap

I am trying to copy the contents of a graphic into a bitmap. I am using this code

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; } } 

If I use a type method

 Graphics g = button1.CreateGraphics(); var bmp = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds)); 

bitmap contains content. But if I draw a graphic object before calling the methods, the bitmap is empty:

 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)); } } 

Why does it work in the first case, and not in the last?

+4
source share
2 answers

As I understand,

  Graphics g = Graphics.FromImage(bmp) 

creates a graphics context for drawing in the image, whereas

  Graphics g = button1.CreateGraphics(); 

creates one control that has already been drawn on the screen. You could draw your dynamically created Bitmap in a PictureBox, and then do the same thing as for your button, something like

  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 } } 

Of course, this just recreates the bitmap that you already have, so I assume you have some other use.

+1
source

Did you try to clear the graphics?

 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)); } } 
0
source

Source: https://habr.com/ru/post/1346938/


All Articles