Search code examples
c#.netwinformsdrawtobitmap

How can I get a screenshot of control? DrawToBitmap not working


I have a pictureBox that's being painted to externally via a dll call.

private void myPictureBox_Paint(object sender, PaintEventArgs e)
{
     dllClass.RefreshEx(LWHANDLE, 0, 0);
}

This is working and all, but I now need to get a screenshot of that picturebox, and it's not working.

Here's what I've tried:

        Control ctrlToDraw = myPictureBox;

        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ctrlToDraw.Width, ctrlToDraw.Height);
        ctrlToDraw.DrawToBitmap(bmp, ctrlToDraw.ClientRectangle); 

I've also attempted to do it via Windows API, but it's resulting in exactly the same result as the above code: a blank (not null) image.

Could anyone name some suggestions apart from taking a screenshot of the whole screen?


Solution

  • I don't know how much control you have over the external program, or how it draws to your picture box, but if you are using createGraphics it wont work.

    private void button1_Click(object sender, EventArgs e)
        {
            //here I am calling the graphics object of the Picture Box, this will draw to the picture box
            //But the DrawToBitmap, will not reflect this change, and once the Picturebox needs to be updated, this will disappear.
            Graphics g = pictureBox1.CreateGraphics();
            g.DrawRectangle(Pens.Blue, 10, 10, 20, 20);
    
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(pictureBox1.Width, pictureBox1.Height);
            Rectangle bounds = new Rectangle(Left, Top, Width, Height);
            pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
            //Draws whatever is in the PictureBox to the Forms BackgroundImage
            this.BackgroundImage = bmp;
            //It will not draw the Blue rectangle
    
        }
    

    If your external program was to draw to a bitmap, then you could set that bitmap to the picturebox background

        Bitmap buffer;
        public Form1()
        {
            InitializeComponent();
            buffer = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        }
    
    
        private void button1_Click(object sender, EventArgs e)
        {
            //draw to the bitmap named buffer
            using (Graphics g = Graphics.FromImage(buffer))
            {
                g.DrawRectangle(Pens.Blue, 10, 10, 20, 20);
            }
            //assign the picturebox image to buffer
            pictureBox1.Image = buffer;
    
            //Now this will show the blue rectangle
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(pictureBox1.Width, pictureBox1.Height);
            Rectangle bounds = new Rectangle(Left, Top, Width, Height);
            pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
    
            this.BackgroundImage = bmp;
        }
    

    EDIT Third Times the Charm right

    This will take a screen shot, cut the picturebox out, and then I changed the Forms Background, just to prove it worked.

    You will need to add

    using System.Drawing.Imaging;
    

    it is for the Pixel format.

     private void button1_Click(object sender, EventArgs e)
        {
            using (Graphics G = pictureBox1.CreateGraphics())
            {
                G.DrawRectangle(Pens.Blue, 10, 10, 10, 10);
            }
            Bitmap BMP = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                            Screen.PrimaryScreen.Bounds.Height,
                                            PixelFormat.Format32bppArgb);
            using (Graphics GFX = Graphics.FromImage(BMP))
            {
                GFX.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                                    Screen.PrimaryScreen.Bounds.Y,
                                    0, 0,
                                    Screen.PrimaryScreen.Bounds.Size,
                                    CopyPixelOperation.SourceCopy);
            }
            Bitmap YourPictureBoxImage = new Bitmap(pictureBox1.Width,pictureBox1.Height);
            using (Graphics g = Graphics.FromImage(YourPictureBoxImage))
            {
                Point np = pictureBox1.PointToScreen(new Point(0, 0));
                g.DrawImage(BMP,new Rectangle(0,0,100,100),new Rectangle(np,pictureBox1.Size),GraphicsUnit.Pixel);
            }
    
            this.BackgroundImage = YourPictureBoxImage;
        }