WebBrowser 內容儲存為圖片

來源:互聯網
上載者:User

概述

最近在Winform的開發中用到了Flash動態圖表FusionCharts Free,這是個開源的flash組件。商業版可以使用FusionCharts V3,免費版本的是FusionCharts
Free v2.2。:http://www.fusioncharts.com/free/download/。大家可以去看看,效果還是非常炫的。商業版比免費版能夠提供更多的圖表,匯出pdf,image,csv等功能,當然免費版這些功能大家就別指望了。

一般flash組件都是以flash的形式在網頁中呈現的。因此如果要在Winform中Flash圖表個人認為有兩種方案。1.
利用WebBrowser控制項,將url執行包含這個flash的網頁。2.利用Flash的com組件shockwave Flash。第一種方式實現方式比較簡單,第二種個人認為最好的是有Flex的組件作為容器,這樣可以根據傳遞進來的參數顯示不同的圖表。

因為免費版沒有匯出pdf,image,csv等功能,所以只好自己去寫了。而且是載入到WebBrowser控制項,因此我對WebBrowser進行了擴充。目前常用的Flash圖表都可以展示,匯出pdf,image,excel,等格式。

相關圖片預覽

先上幾張圖片給大家一個直觀點的認識

  

圖1.匯出的圖片


                圖2.匯出的pdf

遇到的問題

1.          如標題所說的關於WebBrowser.DrawToBitmap問題,因為此控制項是沒有這個方法的,但是你用了也不會出錯,但是問題就來了,有時候可以匯出圖片有時候又不能,載入的網頁裡面不存在Ajax內容之類的。網上有不少對此問題的解決辦法,但是所見之處基本都是錯誤的。一種普遍的做法如下:

代碼

publicvoid WriteBmp(string bmpPath)
        {
            while (webbrowser.ReadyState
!= WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
            System.Drawing.Rectangle r =new System.Drawing.Rectangle(Point.Empty,
                new Size(int.Parse(webbrowser.Document.Body.GetAttribute("scrollWidth")),
int.Parse(webbrowser.Document.Body.GetAttribute("scrollHeight"))));
            Bitmap bmp =new Bitmap(r.Width, r.Height);
            webbrowser.DrawToBitmap(bmp, r);
            bmp.Save(bmpPath);
            bmp.Dispose();
        }

  結果就導致了時而可以時而不可以的問題。對這個問題,國外的網站有不錯的解決方案:
  1.http://bytes.com/topic/c-sharp/answers/605264-taking-screenshot-webbrowser-tab。
  2.

http://efreedom.com/Question/1-2434156/WebBrowser-DrawToBitmap-Methods

    根據上面的方法,我將代碼列出來給大家供參考,以上兩種方法我用過了效果都很棒(上面的就是這樣產生的):

代碼

[DllImport("user32.dll")]
        privatestaticexternbool PrintWindow(IntPtr hwnd, IntPtr hdcBlt,
uint nFlags);

        publicvoid WriteBmp(string bmpPath)
        {

            int screenWidth
= webbrowser.Document.Body.ScrollRectangle.Width;
            int screenHeight
= webbrowser.Document.Body.ScrollRectangle.Height;

            IntPtr myIntptr = webbrowser.Handle;
            int hwndInt
= myIntptr.ToInt32();
            IntPtr hwnd = myIntptr;

            // Set hdc to the bitmap

            Bitmap bm =new Bitmap(screenWidth, screenHeight);
            Graphics g = Graphics.FromImage(bm);
            IntPtr hdc = g.GetHdc();

            // Snapshot the WebBrowser

            bool result
= PrintWindow(hwnd, hdc,
0);
            g.ReleaseHdc(hdc);
            g.Flush();

            // Save the bitmap, if successful

            if (result
==true)
                bm.Save(bmpPath);
        }

第2種方式:

代碼

publicstaticclass ApiConstants
    {
        publicconstint SRCCOPY
=13369376;
    }

    publicstaticclass Utilities
    {
        publicstatic Image CaptureScreen()
        {
            return CaptureWindow(User32.GetDesktopWindow());
        }

        publicstatic Image CaptureWindow(IntPtr handle)
        {

            IntPtr hdcSrc = User32.GetWindowDC(handle);

            RECT windowRect =new RECT();
            User32.GetWindowRect(handle, ref windowRect);

            int width
= windowRect.right
- windowRect.left;
            int height
= windowRect.bottom
- windowRect.top;

            IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
            IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);

            IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);
            Gdi32.BitBlt(hdcDest, 0,
0, width, height, hdcSrc,
0, 0, ApiConstants.SRCCOPY);
            Gdi32.SelectObject(hdcDest, hOld);
            Gdi32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);

            Image image = Image.FromHbitmap(hBitmap);
            Gdi32.DeleteObject(hBitmap);

            return image;
        }
    }

    publicstaticclass User32
    {
        [DllImport("user32.dll")]
        publicstaticextern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        publicstaticextern IntPtr GetWindowDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        publicstaticextern IntPtr GetWindowRect(IntPtr hWnd,
ref RECT rect);
        [DllImport("user32.dll")]
        publicstaticextern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
    }

    publicclass Gdi32
    {
        [DllImport("gdi32.dll")]
        publicstaticexternbool BitBlt(IntPtr hObject,
int nXDest,
int nYDest, int nWidth,
int nHeight, IntPtr hObjectSource,
int nXSrc,
int nYSrc, int dwRop);
        [DllImport("gdi32.dll")]
        publicstaticextern IntPtr CreateCompatibleBitmap(IntPtr hDC,
int nWidth,
int nHeight);
        [DllImport("gdi32.dll")]
        publicstaticextern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        publicstaticexternbool DeleteDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        publicstaticexternbool DeleteObject(IntPtr hObject);
        [DllImport("gdi32.dll")]
        publicstaticextern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
    }

    [StructLayout(LayoutKind.Sequential)]
    publicstruct RECT
    {
        publicint left;
        publicint top;
        publicint right;
        publicint bottom;
    }

    //如果是.net的擴充方法,如果你.net庫版本比較高就去掉注釋
    //public static class ControlExtensions
    //{
    //    public static Image DrawToImage(this Control control)
    //    {
    //        return Utilities.CaptureWindow(control.Handle);
    //    }
    //}

2.關於匯出pdf的問題,大家可以去下載itextsharp開源的組件,學習文檔可以參考

  1. http://itextpdf.com/book/examples.php。java版的

  2. http://www.cnblogs.com/islands/archive/2008/06/27/1231288.html

小結

         以上是自己在Flash動態圖表開發中一點小小的心得,寫出來和大家一起分享,本文的目的給遇到類似問題的朋友一種解決方案,在你搜尋完google,再搜尋baidu發現都不能解決你問題的時候,或許此文能給你點協助。

作者:Jackhuclan
出處:http://jackhuclan.cnblogs.com/

本文著作權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.