[轉帖]C#捕獲網頁為映像

來源:互聯網
上載者:User

參考原文(英文) http://www.codeproject.com/cs/media/IECapture.asp
環境:Visual Studio.NET 2003 語言:C#
系統需求:Windows + iexplore

     該程式的目標很明確,就是捕獲IE瀏覽器開啟的網頁存為映像,附加的需求,我們能自訂映像的儲存品質(控製圖像的大小)。當然我們還要考慮當有多個瀏覽器視窗開啟的時候,我們是捕獲所有視窗的映像。
     廢話不多說,我們開始說說這個程式如何?。

第一步:引用標準DLL

     該程式需要SHDocVw.dll 和 MSHTML.dll的支援,所以在我們的工程中需要添加兩個com組件,在添加引用的對話方塊中選擇com的標籤頁,然後找到Microsoft Internet Controls". 和Microsoft HTML Object Library,添加進來。

第二步:添加必要的名稱空間      

using   System.Text;
using   System.Runtime.InteropServices;
using   System.Diagnostics;
using   System.IO;
using   System.Drawing.Imaging;
using   SHDocVw;
using   mshtml;

第三步:調用user32.dll的函數

[DllImport( " user32.dll " , CharSet = CharSet.Auto)]
public    static    extern   IntPtr FindWindowEx(IntPtr parent   /**/ /* HWND */ ,
   IntPtr next   /**/ /* HWND */ ,   string   sClassName, IntPtr sWindowTitle);

[DllImport( " user32.dll " , ExactSpelling = true , CharSet = CharSet.Auto)]
public    static    extern   IntPtr GetWindow(IntPtr hWnd,   int   uCmd);

[DllImport( " user32.Dll " )]
public    static    extern    void   GetClassName( int   h, StringBuilder s,   int   nMaxCount);

[DllImport( " user32.dll " )]
private    static    extern    bool   PrintWindow(IntPtr hwnd, IntPtr hdcBlt,   uint   nFlags);

public    const    int   GW_CHILD   =    5 ;
public    const    int   GW_HWNDNEXT   =    2 ;

第四步:找到一個開啟的瀏覽器進程,並分配一個Browser Document給它。

SHDocVw.WebBrowser m_browser   =    null ;
SHDocVw.ShellWindows shellWindows   =    new   SHDocVw.ShellWindowsClass();

   // Find first availble browser window.
   // Application can easily be modified to loop through and
   // capture all open windows.
    string   filename;
    foreach   (SHDocVw.WebBrowser ie   in   shellWindows)
     {
       filename   =   Path.GetFileNameWithoutExtension(ie.FullName).ToLower();
        if   (filename.Equals( " iexplore " ))
         {
           m_browser   =   ie;
            break ;  
       }
   }
    if   (m_browser   ==    null )
     {   
       MessageBox.Show( " No Browser Open " );
        return ;
   }

    // Assign Browser Document
    mshtml.IHTMLDocument2 myDoc   =   (mshtml.IHTMLDocument2)m_browser.Document;

第五步:擷取螢幕和網頁的高度和寬度

    // Set scrolling on.
   myDoc.body.setAttribute( " scroll " ,   " yes " ,   0 );

   // Get Browser Window Height
    int   heightsize   =   ( int )myDoc.body.getAttribute( " scrollHeight " ,   0 );
   int   widthsize   =   ( int )myDoc.body.getAttribute( " scrollWidth " ,   0 );

   // Get Screen Height
    int   screenHeight   =   ( int )myDoc.body.getAttribute( " clientHeight " ,   0 );
   int   screenWidth   =   ( int )myDoc.body.getAttribute( " clientWidth " ,   0 );

第六步:捕獲演算法

        這裡要說明的是,其實沒有什麼組件可以讓我們直接把網頁完全捕獲過來,我們還是從基本的一頁一頁捕捉,然後組合整個映像的方法來完成的。
        其基本思想是這樣的:首先捕獲該網頁的第一個片段,然後捲軸滑道下一頁,繼續捕獲下一個片段,然後這個片段組合到一個目標位元影像中,就像縫合起來。這個過程會迴圈進行,直到最後一個片段捕獲完畢,縫合到目標位元影像中去。
          當然我們還可能遇到這樣一種情況,就是網頁比螢幕要寬,這是我們的程式仍然是先捕獲第一個片段,然後瀏覽器捲軸水平移動,捕獲剩餘的部分,然後縫接起來,然後再進行上述的步驟。
//Get bitmap to hold screen fragment.
Bitmap bm = new Bitmap(screenWidth, screenHeight,
     System.Drawing.Imaging.PixelFormat.Format16bppRgb555);

//Create a target bitmap to draw into.
Bitmap bm2 = new Bitmap(widthsize + URLExtraLeft, heightsize +
     URLExtraHeight - trimHeight,
          System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
Graphics g2 = Graphics.FromImage(bm2);

Graphics g = null;
IntPtr hdc;
Image screenfrag = null;
int brwTop = 0;
int brwLeft = 0;
int myPage = 0;
IntPtr myIntptr = (IntPtr)m_browser.HWND;

//Get inner browser window.
int hwndInt = myIntptr.ToInt32();
IntPtr hwnd = myIntptr;
hwnd = GetWindow(hwnd, GW_CHILD);
StringBuilder sbc = new StringBuilder(256);

//Get Browser "Document" Handle
while (hwndInt != 0)
{
      hwndInt = hwnd.ToInt32();
      GetClassName(hwndInt, sbc, 256);

      if(sbc.ToString().IndexOf("Shell DocObject View", 0) > -1)
      {
          hwnd = FindWindowEx(hwnd, IntPtr.Zero,
              "Internet Explorer_Server", IntPtr.Zero);
          break;
      }                
      hwnd = GetWindow(hwnd, GW_HWNDNEXT);
   }

//Get Screen Height (for bottom up screen drawing)
while ((myPage * screenHeight) < heightsize)
{
      myDoc.body.setAttribute("scrollTop", (screenHeight - 5) * myPage, 0);
      ++myPage;
}

//Rollback the page count by one
--myPage;

int myPageWidth = 0;
   while ((myPageWidth * screenWidth) < widthsize)
{
      myDoc.body.setAttribute("scrollLeft", (screenWidth - 5) * myPageWidth, 0);
      brwLeft = (int)myDoc.body.getAttribute("scrollLeft", 0);
      for (int i = myPage; i >= 0; --i)
      {
          //Shoot visible window
          g = Graphics.FromImage(bm);
          hdc = g.GetHdc();
          myDoc.body.setAttribute("scrollTop", (screenHeight - 5) * i, 0);
          brwTop = (int)myDoc.body.getAttribute("scrollTop", 0);
          PrintWindow(hwnd, hdc, 0);
          g.ReleaseHdc(hdc);
          g.Flush();
          screenfrag = Image.FromHbitmap(bm.GetHbitmap());
          g2.DrawImage(screenfrag, brwLeft + URLExtraLeft, brwTop +
             URLExtraHeight);
      }
      ++myPageWidth;
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.