从WebBrowser控件中保存图像

时间:2022-11-11 23:07:40

The following code runs, but the Bitmap generated is shifted down about half an inch and cutoff at the bottom. I checked the image width and height and it is creating an image of the correct size, just the image contents are shifted down and cutoff. I'm stumped... any ideas?

下面的代码运行,但是生成的位图会向下移动大约半英寸,并在底部切断。我检查了图像的宽度和高度,它正在创建一个正确大小的图像,只是图像内容被向下移动和切断。我难住了……什么好主意吗?

    using mshtml;
    using System.Drawing;
    using System.Runtime.InteropServices;

    [ComImport, InterfaceType((short)1), Guid("3050F669-98B5-11CF-BB82-00AA00BDCE0B")]
    private interface IHTMLElementRenderFixed
    {
        void DrawToDC(IntPtr hdc);
        void SetDocumentPrinter(string bstrPrinterName, IntPtr hdc);
    }

    public Bitmap GetImage(string id)
    {
        HtmlElement e = webBrowser1.Document.GetElementById(id);
        IHTMLImgElement img = (IHTMLImgElement)e.DomElement;
        IHTMLElementRenderFixed render = (IHTMLElementRenderFixed)img;

        Bitmap bmp = new Bitmap(img.width, img.height);
        Graphics g = Graphics.FromImage(bmp);
        IntPtr hdc = g.GetHdc();
        render.DrawToDC(hdc);
        g.ReleaseHdc(hdc);

        return bmp;
    }

4 个解决方案

#1


3  

What you are doing is rendering the image as it is rendered by the browser with all the styles. I don't know if this is what your realy want? If you only want to download the image then it is easier to solve it with a web request as described in hte other answers.

您所做的是呈现由浏览器呈现的具有所有样式的图像。我不知道这是不是你真正想要的?如果您只想下载这个映像,那么使用一个web请求来解决这个问题就会更容易,如hte其他答案所述。

If you realy want to render than the first step is to change

如果你真的想渲染,第一步就是改变

Bitmap bmp = new Bitmap(img.width, img.height);

to

Bitmap bmp = new Bitmap(e.OffsetRectangle.Width, e.OffsetRectangle.Height);

Now you get the complete rendered web browser image.

现在您将获得完整的呈现的web浏览器映像。

If you want a perfect solution even for big images you also have to scroll around and get the image tile by tile.

如果你想要一个完美的解决方案,即使是对于大的图像,你也必须滚动,得到图像块的一个。

#2


2  

to start with I believe the img element you getting has a different size other than what is the actual image size.

首先,我相信你得到的img元素的大小与实际的图像大小不同。

Secondly, why don't you use direct System.Net.WebRequest and download the actual image from the URL. you already have the URL and Already have the IMG element information, infact if you not show the webbrowser try using System.Net.WebRequest, this way you can verify what content type you getting is it an actual image or place holder.

其次,为什么不直接使用System.Net呢?WebRequest和从URL下载真实的图像。您已经有了URL,并且已经有了IMG元素信息,事实上,如果不显示web浏览器,请使用System.Net。WebRequest,通过这种方式,你可以验证你得到的内容类型是一个真实的图片还是一个放置器。

http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx

http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx

#3


1  

If you have the address, you can save it using:

如果你有地址,你可以用:

client.DownloadFile

When client is a System.Net.WebClient

当客户端是System.Net.WebClient时

#4


-1  

Imports System.Net
Imports System.Runtime.InteropServices
Imports mshtml
--Add reference Microsoft Html Object Library

Sub Dowork()
Dim x = WebBrowser1.Document.GetElementsByTagName("img")
For i As Integer = 0 To x.Count - 1
If x(i).GetAttribute("alt") = "Captcha image" Then
GetImage(x(i)).Save("captcha.png", Imaging.ImageFormat.Png)
End If
Next
End Sub

<ComImport>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<Guid("3050F669-98B5-11CF-BB82-00AA00BDCE0B")>
Public Interface IHTMLElementRenderFixed
Sub DrawToDC(hdc As IntPtr)
Sub SetDocumentPrinter(bstrPrinterName As String, hdc As IntPtr)
End Interface




Public Function GetImage(e As HtmlElement) As Bitmap
    Dim img As IHTMLImgElement = TryCast(e.DomElement, IHTMLImgElement)
    Dim render As IHTMLElementRenderFixed = TryCast(img, IHTMLElementRenderFixed)
    Dim bmp As Bitmap = New Bitmap(e.OffsetRectangle.Width, e.OffsetRectangle.Height)
    Dim g As Graphics = Graphics.FromImage(bmp)
    Dim hdc As IntPtr = g.GetHdc()
    render.DrawToDC(hdc)
    g.ReleaseHdc(hdc)
    Return bmp
End Function

#1


3  

What you are doing is rendering the image as it is rendered by the browser with all the styles. I don't know if this is what your realy want? If you only want to download the image then it is easier to solve it with a web request as described in hte other answers.

您所做的是呈现由浏览器呈现的具有所有样式的图像。我不知道这是不是你真正想要的?如果您只想下载这个映像,那么使用一个web请求来解决这个问题就会更容易,如hte其他答案所述。

If you realy want to render than the first step is to change

如果你真的想渲染,第一步就是改变

Bitmap bmp = new Bitmap(img.width, img.height);

to

Bitmap bmp = new Bitmap(e.OffsetRectangle.Width, e.OffsetRectangle.Height);

Now you get the complete rendered web browser image.

现在您将获得完整的呈现的web浏览器映像。

If you want a perfect solution even for big images you also have to scroll around and get the image tile by tile.

如果你想要一个完美的解决方案,即使是对于大的图像,你也必须滚动,得到图像块的一个。

#2


2  

to start with I believe the img element you getting has a different size other than what is the actual image size.

首先,我相信你得到的img元素的大小与实际的图像大小不同。

Secondly, why don't you use direct System.Net.WebRequest and download the actual image from the URL. you already have the URL and Already have the IMG element information, infact if you not show the webbrowser try using System.Net.WebRequest, this way you can verify what content type you getting is it an actual image or place holder.

其次,为什么不直接使用System.Net呢?WebRequest和从URL下载真实的图像。您已经有了URL,并且已经有了IMG元素信息,事实上,如果不显示web浏览器,请使用System.Net。WebRequest,通过这种方式,你可以验证你得到的内容类型是一个真实的图片还是一个放置器。

http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx

http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx

#3


1  

If you have the address, you can save it using:

如果你有地址,你可以用:

client.DownloadFile

When client is a System.Net.WebClient

当客户端是System.Net.WebClient时

#4


-1  

Imports System.Net
Imports System.Runtime.InteropServices
Imports mshtml
--Add reference Microsoft Html Object Library

Sub Dowork()
Dim x = WebBrowser1.Document.GetElementsByTagName("img")
For i As Integer = 0 To x.Count - 1
If x(i).GetAttribute("alt") = "Captcha image" Then
GetImage(x(i)).Save("captcha.png", Imaging.ImageFormat.Png)
End If
Next
End Sub

<ComImport>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<Guid("3050F669-98B5-11CF-BB82-00AA00BDCE0B")>
Public Interface IHTMLElementRenderFixed
Sub DrawToDC(hdc As IntPtr)
Sub SetDocumentPrinter(bstrPrinterName As String, hdc As IntPtr)
End Interface




Public Function GetImage(e As HtmlElement) As Bitmap
    Dim img As IHTMLImgElement = TryCast(e.DomElement, IHTMLImgElement)
    Dim render As IHTMLElementRenderFixed = TryCast(img, IHTMLElementRenderFixed)
    Dim bmp As Bitmap = New Bitmap(e.OffsetRectangle.Width, e.OffsetRectangle.Height)
    Dim g As Graphics = Graphics.FromImage(bmp)
    Dim hdc As IntPtr = g.GetHdc()
    render.DrawToDC(hdc)
    g.ReleaseHdc(hdc)
    Return bmp
End Function