• 轻松实现 Killer 级应用 Snap (转)


    < DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd>

    转自:http://www.cnblogs.com/jessezhao/archive/2006/12/25/602656.html
    获取 windows application 的截图很容易,但是获取一个网页的截图往往让人感觉摸不着头脑,不知道如何下手。在 windows application 中我们可以使用 .Net framework 2.0 的 WebBrowser 组件来获取我们需要的网站,然后使用 .DrawToBitmap 函数去获取当前网站的 bitmap。这个组件在 windows application 中工作良好,那他在 Web site 中的表现如何呢?能不能实现我们想要的功能呢?

    不要忘记 Asp.net 和windows application 都是在 .net framework 上运行的。这就使我们可以把在 Windows application 实现方法用在 asp.net application 上面。我的初步想法是初始化一个隐藏的 WebBrowser 组件,并且在其中加载我们的 web site 以便参生截图。当然我们还是会面对前面我们提到的 asp.net application 和 web forms application 的问题。

    使用 WebBrowser 组件

    Dim MyBrowser As New WebBrowser
    MyBrowser.ScrollBarsEnabled = False
    MyBrowser.Size = New Size(1027, 768)
    MyBrowser.Navigate(”http://www.deveload.com”)
    Dim myBitmap As New Bitmap(1024, 768)
    Dim DrawRect As New Rectangle(0, 0, 1024, 768)
    MyBrowser.DrawToBitmap(myBitmap, DrawRect)

    在我们定义自己的 WebBrowser 变量之后,我们会给他设置一些属性如把 ScrollBarsEnabled 设置成 false 等。我们调用 navigate 方法去打开我的网站 “www.pinzui.cn”。接下来我们定义了 BitMap 变量, 绘图区域(DrawRect)并且调用 DrawToBitmap 方法获取我们的截图。看起来仿佛一切都是正常的,但是当你试图运行程序的时候,你会获得 too many errors。第一个问题就是我们不能等待我们想要截图的网站被 WebBrowser 组件完全加载就去获取截图。其实我们只是获取了一个网站加载中的实例的截图。通常情况下我们需要等待想要被截图的网站完全加载才能去获取截图。

    MyBrowser.Navigate(Me.URL)
    While MyBrowser.ReadyState <> WebBrowserReadyState.Complete
    Application.DoEvents()
    End While

    在我们网站开始加载的时候,我们只是做哑循环去等待我们想要截图的网站被完全加载。为什么我们要试用 Application.DoEvents()呢,这是个技巧,我晚会给大家解释。下面是我们遇到的下一个问题,我们使用的 WebBrowser 空间实际上是一个 COM 对象。我们需要在一个单独的线程里自由的使用 WebBrowser 控件。我们所有的获取截图的程序应该被控制运行在一个独立的线程里面。

    Dim NewTh As New Threading.Thread(AddressOf DoIt)
    NewTh.SetApartmentState(Threading.ApartmentState.STA)
    NewTh.Start()

    让我们回到前面那个等待 WebBrowser 控件的循环里。重新思考一下。我们使用一个单独的线程在不停的 loop 等待我们想要截图的网站完全加载。通常情况下这个循环会使我们的程序死锁,直到网页加载完循环结束才把控制权重新交付给 WebBrowser。但是为什么我们的程序没有被死锁呢,对了,Application.DoEvents()就是答案。这个方法会在循环过程中把控制权交付给我们的 WebBrowser 控件。

    创建网页截图

    Dim imgOutput As System.Drawing.Image = myBitmap
    Dim oThumbNail As System.Drawing.Image = New Bitmap(twidth, theight, & _
    imgOutput.PixelFormat)
    Dim g As Graphics = Graphics.FromImage(oThumbNail)
    g.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
    g.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
    g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBilinear
    Dim oRectangle As Rectangle = New Rectangle(0, 0, twidth, theight)
    g.DrawImage(imgOutput, oRectangle

    在上面的代码中,我们定义了 imgOutput 并且把名为 myBitmap 的原始图像付给他。twidth,theight 是表示我们目标截图大小的变量。我们通过具有目标大小的哑图像创建了一个 grapics 对象。我们为 graphics 对象设置了一下哦属性,并且调用了 DrawImage 方法来产生截图。

    最终的类

    Imports System
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Windows.Forms
    Imports System.Diagnostics
    Namespace GetSiteThumbnail
    Public Class GetImage
    Private S_Height As Integer
    Private S_Width As Integer
    Private F_Height As Integer
    Private F_Width As Integer
    Private MyURL As String
    Property ScreenHeight() As Integer
    Get
    Return S_Height
    End Get
    Set(ByVal value As Integer)
    S_Height = value
    End Set
    End Property
    Property ScreenWidth() As Integer
    Get
    Return S_Width
    End Get
    Set(ByVal value As Integer)
    S_Width = value
    End Set
    End Property
    Property ImageHeight() As Integer
    Get
    Return F_Height
    End Get
    Set(ByVal value As Integer)
    F_Height = value
    End Set
    End Property
    Property ImageWidth() As Integer
    Get
    Return F_Width
    End Get
    Set(ByVal value As Integer)
    F_Width = value
    End Set
    End Property
    Property WebSite() As String
    Get
    Return MyURL
    End Get
    Set(ByVal value As String)
    MyURL = value
    End Set
    End Property
    Sub New(ByVal WebSite As String, ByVal ScreenWidth As Integer, &_
    ByVal ScreenHeight As Integer, ByVal ImageWidth As Integer,&_
    ByVal ImageHeight As Integer)
    Me.WebSite = WebSite
    Me.ScreenWidth = ScreenWidth
    Me.ScreenHeight = ScreenHeight
    Me.ImageHeight = ImageHeight
    Me.ImageWidth = ImageWidth
    End Sub
    Function GetBitmap() As Bitmap
    Dim Shot As New WebPageBitmap(Me.WebSite, Me.ScreenWidth, &_
    Me.ScreenHeight)
    Shot.GetIt()
    Dim Pic As Bitmap = Shot.DrawBitmap(Me.ImageHeight, &_
    Me.ImageWidth)
    Return Pic
    End Function
    End Class
    Class WebPageBitmap
    Dim MyBrowser As WebBrowser
    Dim URL As String
    Dim Height As Integer
    Dim Width As Integer
    Sub New(ByVal url As String, ByVal width As Integer, &_
    ByVal height As Integer)
    Me.Height = height
    Me.Width = width
    Me.URL = url
    MyBrowser = New WebBrowser
    MyBrowser.ScrollBarsEnabled = False
    MyBrowser.Size = New Size(Me.Width, Me.Height)
    End Sub
    Sub GetIt()
    MyBrowser.Navigate(Me.URL)
    While MyBrowser.ReadyState <> WebBrowserReadyState.Complete
    Application.DoEvents()
    End While
    End Sub
    Function DrawBitmap(ByVal theight As Integer, &_
    ByVal twidth As Integer) As Bitmap
    Dim myBitmap As New Bitmap(Width, Height)
    Dim DrawRect As New Rectangle(0, 0, Width, Height)
    MyBrowser.DrawToBitmap(myBitmap, DrawRect)
    Dim imgOutput As System.Drawing.Image = myBitmap
    Dim oThumbNail As System.Drawing.Image = New Bitmap(twidth, &_
    theight, imgOutput.PixelFormat)
    Dim g As Graphics = Graphics.FromImage(oThumbNail)
    g.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
    g.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
    g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBilinear
    Dim oRectangle As Rectangle = New Rectangle(0, 0, twidth, theight)
    g.DrawImage(imgOutput, oRectangle)
    Try
    Return oThumbNail
    Catch ex As Exception
    Finally
    imgOutput.Dispose()
    imgOutput = Nothing
    MyBrowser.Dispose()
    MyBrowser = Nothing
    End Try
    End Function
    End Class
    End Namespace

    如何使用代码?

    Partial Class _Default
    Inherits System.Web.UI.Page
    Protected Sub Button1_Click(ByVal sender As Object, &_
    ByVal e As System.EventArgs) Handles Button1.Click
    Dim NewTh As New Threading.Thread(AddressOf DoIt)
    NewTh.SetApartmentState(Threading.ApartmentState.STA)
    NewTh.Start()
    End Sub
    Sub DoIT()
    Try
    Dim thumb As New GetSiteThumbnail.GetImage("
    1024, 768, 320, 240)
    Dim x As System.Drawing.Bitmap = thumb.GetBitmap()
    x.Save("C:\Inetpub\wwwroot\screeny\deveload.jpg")
    Catch ex As Exception
    Dim y As System.IO.StreamWriter = System.IO.File.CreateText("C:\Inetpub\wwwroot\screeny\error.txt")
    y.WriteLine(ex.Message & vbCrLf & ex.Source)
    y.Flush()
    y.Close()
    End Try
    End Sub
    End Class

    上面的代码会创建一个我们写的类的实例并且获取网页截图。如果有什么错误发生了,他会创建一个文本文件,并且把错误写到里面。但是千万不要忘记 DoIT 类会运行在一个独立的线程里面。

    Conclusion(结论)

    这个系统可以完美工作在90%以上的网站。但是那些通过 AJAX 或者 Flash 在网页加载完成后在调用外部数据的网站,这个系统就不太管用了。

    PS:我把它改写成C#的,调试了好长时间都没有通过。原文也没有提供源码。在 Web application 里面好像是不能引用System.Windows.Form。困惑了一个晚上了,今天把翻译好的文章放出来,各位大侠看看,能不能给出个解决方案或者源码之类的。

  • 相关阅读:
    【Springboot】Springboot整合Ehcache
    时间戳转化正常的时间格式
    申请抖音企业认证流程
    js与原生进行交互
    vim 高亮
    shell 关于路径查询显示pwd
    shell 关于字符切割 cut
    linux ubuntu 关于vim得一些基本命令
    shell 在终端中打开另一个终端执行命令
    shell 获取时间
  • 原文地址:https://www.cnblogs.com/netcorner/p/2912094.html
Copyright © 2020-2023  润新知