0

Here is what I'm trying to do:

  • I have a winforms control in a C# project that displays a map.
  • I want to capture an image of the loaded map, and I need this image to be a very large continuous portion of the map. To do this I can create the dimensions of the map control to be huge (> 4k x 4k pixels)
  • The problem I have is that I cannot capture that control's client area to a bit map without issues.

I have tried the following without much luck:

  • This will save the image, but it captures any window on top as well as the taskbar and offscreen content is white:

        var controlGraphic = mapControl.CreateGraphics();
    
        var img = new Bitmap(mapControl.Width, mapControl.Height, controlGraphic);
        var imgGraphic = Graphics.FromImage(img);
        var controlGraphicDc = controlGraphic.GetHdc();
        var imgGraphicDc = imgGraphic.GetHdc();
    
        BitBlt(imgGraphicDc, 0, 0, mapControl.ClientRectangle.Width, mapControl.ClientRectangle.Height, controlGraphicDc, 0, 0, SRCCOPY);
    
        controlGraphic.ReleaseHdc(controlGraphicDc);
        imgGraphic.ReleaseHdc(imgGraphicDc);
    
        img.Save(fileName, ImageFormat.Png);
    
  • I tried code similar to the last post in this link, but it doesn't seem to work any better: Capture the screen shot using .NET

So I don't think it has anything to do with the map control per se, and I think you could use any control (i.e. WebBrowser) and resize it to be huge and get the same effect.

I'm wondering if anybody has done something similar, or maybe there is a way to maybe nest the control in some scrollable control and somehow capture its contents, or maybe a different context and do a capture? I might be able to use WPF if that helps in anyway.

Thanks.

Example with WebBrowser control that shows same result (new winforms with WebBrowser control on it and button):

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WebBrowserCaptureTest
{
    public partial class Form1 : Form
    {
        [DllImport("gdi32.dll")]
        private static extern bool BitBlt(
        IntPtr hdcDest, // handle to destination DC
        int nXDest, // x-coord of destination upper-left corner
        int nYDest, // y-coord of destination upper-left corner
        int nWidth, // width of destination rectangle
        int nHeight, // height of destination rectangle
        IntPtr hdcSrc, // handle to source DC
        int nXSrc, // x-coordinate of source upper-left corner
        int nYSrc, // y-coordinate of source upper-left corner
        int dwRop // raster operation code
        );

        private const int SRCCOPY = 0xCC0020;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            webBrowser1.SetBounds(0, 0, 4096, 4096);
            webBrowser1.Navigate(@"http://www.google.com");
        }

        private void CaptureControl(System.Windows.Forms.Control control, string fileName)
        {
            var controlGraphic = control.CreateGraphics();

            var img = new Bitmap(control.Width, control.Height, controlGraphic);
            var imgGraphic = Graphics.FromImage(img);
            var controlGraphicDc = controlGraphic.GetHdc();
            var imgGraphicDc = imgGraphic.GetHdc();

            BitBlt(imgGraphicDc, 0, 0, control.ClientRectangle.Width, control.ClientRectangle.Height, controlGraphicDc, 0, 0, SRCCOPY);

            controlGraphic.ReleaseHdc(controlGraphicDc);
            imgGraphic.ReleaseHdc(imgGraphicDc);

            img.Save(fileName, ImageFormat.Png);
        }

        static void DrawControlToBitmap(Control ctrl, string fileName)
        {
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ctrl.Width, ctrl.Height);
            ctrl.DrawToBitmap(bmp, ctrl.ClientRectangle);
            bmp.Save(fileName);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CaptureControl(this.webBrowser1, "Capture.png");
            DrawControlToBitmap(webBrowser1, "Capture_B.png");
        }
    }
}

Note 2 things:

  1. Control.DrawToBitmap results in a Totally White image in the example using a WebBrowser control and
  2. The map control I am using is an activeX control that doesn't support that method.
Community
  • 1
  • 1
Avery
  • 249
  • 1
  • 4
  • 11
  • sorry but i dont understand what u really need,your form loads a map and paints it or is it an image,and what do you need exactly?...some more context and code might help out... – terrybozzio Sep 12 '14 at 15:43
  • I've added an example using a WebBrowser control. – Avery Sep 12 '14 at 16:04
  • i still dont understand what you really need but maybe its changing the code instead of the navigated place it inside the DocumentCompleted event and try it out. – terrybozzio Sep 12 '14 at 16:22
  • What I am trying to do is capture the client area of a control. What that control is, doesn't really matter. The WebBrowser is used for illustration. Take a control, make it very large (beyond the area of your normal screen), have it do something that updates its display and then try to capture it into a bitmap. – Avery Sep 12 '14 at 16:25
  • in the document completed it shows the whole webbrowser and nothing more(the image saved)...navigated is begining loading the document. – terrybozzio Sep 12 '14 at 16:32
  • Ok fair enough, I updated the example to make it more explicit. There is now a button on the form. Click the button capture the image. I think you are missing the point though, the output image is 4096x4096 like I want, but only the upper left corner will show the browser control. You can resize the form to make the image bigger, but you can't go any bigger than the screen size. – Avery Sep 12 '14 at 17:40
  • This question is not a duplicate as Hans Passant has marked it to be without fully understanding the problem. How do I get what he did undone?!! – Avery Sep 12 '14 at 18:48
  • 1
    `The map control I am using is an activeX control that doesn't support that method.` That seems to be what the question is really about. Maybe you should document that control instead of making people play with WebBrowser controls, etc. – LarsTech Sep 12 '14 at 18:54
  • Well thanks for that comment Lars. I think I have made it clear that the net effect is the same as using a WebBrowser, etc. I have shown that you can't use the DrawtoBitmap. Ergo, if you can make it work with the web browser, sans DrawToBitmap, then it stands to reason that it will work with my map control. – Avery Sep 12 '14 at 19:03
  • Hans, thanks for torpedoing my post, leaving me without an answer and wasting more than one person's time. Since nobody can link to this post anymore it is doubtful this will be read ever again. How about next time you let questions play out for more than an hour before stamping the life out of a post. – Avery Sep 12 '14 at 20:22

0 Answers0