如何把網頁內容存成圖檔

18:10 0 Comments A+ a-

昨天看到雞皮哥寫把網頁內容寫成圖檔存查,今天就換我被要求要處理這樣的功能。幸好之前有先做過功課,怎麼做這樣的功能心裡早有個底。 程式很易了解,一路順手寫下,也完全沒有做任何註解。
應用原理很簡單,以多執行緒,偷開一個瀏覽器把指定的網頁讀出來,然後再把瀏覽器讀到的內容寫成指定圖檔格式。真的就這麼簡單。不信,來看看程式碼吧。 Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading

Public Class PageContentToImage
  Private _height As Integer = 0
  Private _width As Integer = 0
  Private _pageurl As String = String.Empty

  Private img As Bitmap = Nothing

  Public Property Height() As Integer
    Get
      Return _height
    End Get
    Set(ByVal value As Integer)
      _height = value
    End Set
  End Property

  Public Property Width() As Integer
    Get
      Return _width
    End Get
    Set(ByVal value As Integer)
      _width = value
    End Set
  End Property

  Public Property PageUrl() As String
    Get
      Return _pageurl
    End Get
    Set(ByVal value As String)
      _pageurl = value
    End Set
  End Property

  Private Function ConvertPage() As Bitmap
    Dim thrdCurrent As New Thread(New ThreadStart(AddressOf CreateSnap))
    With thrdCurrent
      .SetApartmentState(ApartmentState.STA)
      .Start()
      .Join()
    End With

    Return img
  End Function

  Private Sub CreateSnap()
    Using browsePage As New WebBrowser()
      With browsePage
        .ScrollBarsEnabled = False
        .Navigate(Me.PageUrl)
        AddHandler .DocumentCompleted, AddressOf Browser_LoadCompleted

        While .ReadyState <> WebBrowserReadyState.Complete
          Application.DoEvents()
        End While
      End With
    End Using
  End Sub

  Private Sub Browser_LoadCompleted(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
    Dim pageOpened As WebBrowser = DirectCast(sender, WebBrowser)
    With pageOpened
      .ClientSize = New Size(Width, Height)
      .ScrollBarsEnabled = False
      img = New Bitmap(Width, Height)
      .BringToFront()
      .DrawToBitmap(img, .Bounds)
    End With
  End Sub

  Public Sub SaveAsFile(ByVal pathtosave As String)
    ConvertPage.Save(pathtosave, Imaging.ImageFormat.Png)
  End Sub
End Class


稍微解釋一下,圖檔的格式我直接指定為 png,可視需求改變。或者也可以改寫,依狀況自動調整存檔格式,讓它更有彈性。 我們只要把上面的程式,建立成一個類別庫,再由需要使用的網站程式中來引用即可。

要如何使用呢?如下面的示範
Dim slice As New HtmlToImage.PageContentToImage
With slice
  .Height = 600 ''圖高
  .Width = 1024 ''圖寬
  .PageUrl = "http://www.dotblogs.com.tw" ''要存成圖的網頁
  .SaveAsFile(MapPath("") & "\screenshot.png") ''存檔於指定的路徑
End With

Response.Write(""<img src=""screenshot.png"" with=""50%"" height=""50%"" />"")


下圖是用該元件抓下來的點部落的例圖



要注意的是,存檔的路徑必須有 asp.net 可以寫入的權限,否則會有錯誤產生。 另外,因為技術限制,無法自動求得網頁的實際高度(總長)。只得從 javascript 下手,求得網頁寬度,及高度,再以 __doPost(); 的技巧來實作。 以上,謝謝收看 :)