c# - 从 Internet Explorer 渲染图像

标签 c# javascript html internet-explorer screenshot

我正在尝试从 Internet Explorer 保存完整的渲染图像。

不幸的是,我不能使用 WinForm 组件“WebBrowser”或第三方组件,如 HtmlCapture.Net 或在线服务或类似的东西,因为我有几个限制。但我仍然希望使用 IE 足以解决我的任务。

我的代码的主要部分如下所示:

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

但我总是只能得到黑色图像。

我也尝试过使用 BitBlt,但如果网页太大,图像的底部就会变黑,据我所知,这是因为 BltBit 的性质,它假设只复制窗口的可见部分。 CopyFromScreen 出于同样的原因不起作用。

除了this,我还有其他选择吗?解决方案?

无论如何,如果有人给我任何建议或正确的指导,我真的很感激。

更新:

我试过了。像那样

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

但我在这里也没有成功。

我也尝试过使用 IHTMLElementRender 但这个转换失败了:

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

无论如何,这里是完整的代码,我认为它与 Winforms 的 WebBrowser 控件一起工作得很好。

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

最佳答案

如果您想要一个临时屏幕截图来查看您想要的页面,请尝试截取当前事件的屏幕截图,然后将其输出为图像按钮并为 Screen1.class 添加 onclicklistener

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

或者另外/两者兼而有之

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

关于c# - 从 Internet Explorer 渲染图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12467446/

相关文章:

c# - ASP.NET MVC 子目录

c# - 使用接口(interface)有什么好处?

javascript - 如何防止 jQuery 事件冒泡到父元素?

javascript - 如何在不刷新整个页面的情况下更新 HTML 文档中的 php 变量?

javascript - PhantomJS:无法在描述中进行设置/拆卸

c# - c#中的字符串拆分

相当于 Python freezegun 或 Ruby timecop 的 Java 或 C#

html - 媒体查询在 IE9 iframe 中失败

javascript - 在按钮内渲染 SVG 图标?

javascript - 在 jquery 中向 dataTable 添加行的函数给出 TypeError