简体   繁体   中英

Rendering image from Internet Explorer

I'm trying to save full rendered image from Internet Explorer.

Unfortunately, I can't use WinForm component "WebBrowser" or third party components like HtmlCapture.Net or On-line services or smth like that because I have several limitations. But I still hope that using a IE is enough for solving my task.

The main part of my code looks like this:

      SHDocVw.WebBrowser wb = GetBrowser();
      wb.DocumentComplete += wb_DocumentComplete2;
      wb.Navigate(_url);

      private void wb_DocumentComplete2(object pDisp, ref object URL)
    {
        var iwb2 = (IWebBrowser2) pDisp;
        var document = (IHTMLDocument2) iwb2.Document;

        if (heightsize > 0 && widthsize > 0)
        {
            IntPtr _hwnd = IntPtr.Zero;
            try
            {
                _hwnd = new IntPtr(iwb2.HWND);
            }
            catch (Exception e)
            {
            }

            if (_hwnd != IntPtr.Zero)
            {
                //Start here
                RECTL r = new RECTL
                              {
                                  top = 0,
                                  left = 0,
                                  bottom = heightsize,
                                  right = widthsize
                              };
                IViewObject ivo = document as IViewObject;
                if (ivo != null)
                {
                    using (Bitmap bmp = new Bitmap(widthsize, heightsize))
                    {
                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            //get the handle to the device context and draw
                            IntPtr hdc = g.GetHdc();
                            ivo.Draw(DVASPECT.DVASPECT_CONTENT, 1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, hdc, ref r, ref r, IntPtr.Zero, 0);
                            g.ReleaseHdc(hdc);
                        }
                        String filename = @"C:\" + Guid.NewGuid() + ".png";
                        bmp.Save(filename, ImageFormat.Png);
                    }
                }
            }
        }
    }

But I'm always get only black image.

I also tryed to use BitBlt but if web page is too big the bottom part of image is black and as far as I know it's because of the nature of BltBit which suppose to copy only visible part of the window. CopyFromScreen doesn't work for same reason.

Do I have any options except this solution?

Anyways, I really appreciate if somebody give my any suggestion or right direction how do do this.

UPDATED:

I tried smth. like that

using (Graphics graphics = Graphics.FromImage(new Bitmap(Width,Height)))
        {
            IntPtr hdcDestination = graphics.GetHdc();
            tagRECT lprcBounds = new tagRECT(0, 0, Width, Height);
            tagRECT lprcWBounds = new tagRECT(0, 0, Width, Height);
            int i = viewObject.Draw(1, 1, IntPtr.Zero, IntPtr.Zero, hdcDestination, IntPtr.Zero, lprcBounds, lprcWBounds, IntPtr.Zero, 0);
            IntPtr hdcMemory = Helper.Gdi32.CreateCompatibleDC(hdcDestination);
            IntPtr bitmap = Helper.Gdi32.CreateCompatibleBitmap(hdcDestination, Width, Height);
            if (bitmap != IntPtr.Zero)
            {
                IntPtr hOld = Helper.Gdi32.SelectObject(hdcMemory, bitmap);
                Helper.Gdi32.BitBlt(hdcMemory,0, 0,Width, Height, hdcDestination, 0, 0, Helper.Gdi32.SRCCOPY);
                Helper.Gdi32.SelectObject(hdcMemory, hOld);
                Helper.Gdi32.DeleteDC(hdcMemory);
                graphics.ReleaseHdc(hdcDestination);
                Image img = Image.FromHbitmap(bitmap);
                String filename = @"C:\" + Guid.NewGuid() + ".png";
                img.Save(filename, ImageFormat.Png);
            }
        }

But I'm not succeed here too.

I also tried to use IHTMLElementRender but this cast is fails:

IHTMLElement element = (IHTMLElement) document.body; // Okay, element isn't null
IHTMLElementRender render = (IHTMLElementRender) element; //Fails!

Anyways here is complete code and I think it works good enough with WebBrowser control from Winforms.

private void OnDocumentComplete(object sender, DWebBrowserEvents2_DocumentCompleteEvent e)
{
    IHTMLDocument2 document = (IHTMLDocument2) this.axWebBrowser1.Document;
    if (document != null)
    {
          IHTMLElement element = (IHTMLElement) document.body;
          if (element != null)
          {
              IHTMLElementRender render = (IHTMLElementRender) element;
              if (render != null)
              {
                    using (Graphics graphics = this.pictureBox1.CreateGraphics())
                    {
                        IntPtr hdcDestination = graphics.GetHdc();
                        render.DrawToDC(hdcDestination);
                        IntPtr hdcMemory = GDI32.CreateCompatibleDC(hdcDestination);
                        IntPtr bitmap = GDI32.CreateCompatibleBitmap(
                              hdcDestination, 
                              this.axWebBrowser1.ClientRectangle.Width, this.axWebBrowser1.ClientRectangle.Height
                              );

                        if (bitmap != IntPtr.Zero)
                        {
                              IntPtr hOld = (IntPtr) GDI32.SelectObject(hdcMemory, bitmap);
                              GDI32.BitBlt(
                                  hdcMemory,
                                  0, 0,
                                  this.axWebBrowser1.ClientRectangle.Width, this.axWebBrowser1.ClientRectangle.Height,
                                  hdcDestination,
                                  0, 0,
                                  (int) GDI32.TernaryRasterOperations.SRCCOPY
                                  );
                              GDI32.SelectObject(hdcMemory, hOld);
                              GDI32.DeleteDC(hdcMemory);
                              graphics.ReleaseHdc(hdcDestination);

                              this.pictureBox.Image = Image.FromHbitmap(bitmap);
                        }
                    }
              }
          }
    }
}

If you wanted a temporary screenshot for viewing which page you wanted try screenshotting the current activity then outputting it as a imagebutton and add the onclicklistener for the Screen1.class

View  content = findViewById(R.id.blankview);
getScreen();
}

private void getScreen(){
Bitmap bitmap = content.getDrawingCache();
File file = new File("/sdcard/test.png");
try 
{
    file.createNewFile();
    FileOutputStream ostream = new FileOutputStream(file);
    bitmap.compress(CompressFormat.PNG, 100, ostream);
    ostream.close();
} 
catch (Exception e) 
{
    e.printStackTrace();
}

}

Or Alternatively/Both

View v = view.getRootView();
v.setDrawingCacheEnabled(true);
Bitmap b = v.getDrawingCache();
String extr =     Environment.getExternalStorageDirectory().toString();
File myPath = new File(extr, getString(R.string.free_tiket)+".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
    MediaStore.Images.Media.insertImage(getContentResolver(), b, "Screen", "screen");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM