捕獲網頁爲圖像

參考原文(英文)http://www.codeproject.com/cs/media/IECapture.asp
環境:Visual Studio.NET 2003 語言:C#
系統需求:Windows + iexplore                                                       附件:捕獲網頁爲圖像程序
捕獲效果圖:

         該程序的目標很明確,就是捕獲IE瀏覽器打開的網頁存爲圖像,附加的需求,我們能自定義圖像的保存質量(控制圖像的大小)。當然我們還要考慮當有多個瀏覽器窗口打開的時候,我們是捕獲所有窗口的圖像。
        廢話不多說,我們開始說說這個程序如何實現。

第一步:
         該程序需要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;
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章