从WebBrowser控件中保存图片

4
以下代码可以运行,但生成的Bitmap向下偏移了约半英寸,并在底部被裁剪。我检查了图像的宽度和高度,它正在创建正确大小的图像,只是图像内容向下偏移并被裁剪。我很困惑...有任何想法吗?
    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个回答

3
你正在做的是将图像与所有样式一起渲染,就像浏览器一样。我不知道这是否是你真正想要的?如果你只想下载图片,那么可以更容易地通过网络请求来解决,就像其他答案中描述的那样。
如果你真的想渲染,则第一步是更改:
Bitmap bmp = new Bitmap(img.width, img.height);

为了

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

现在您可以获得完整的渲染网页浏览器图像。

如果您想要一个完美的解决方案,即使是大型图像,您也需要滚动并逐个获取图像瓷砖。


滚动对于大型图片是否真的必要?我的WebBrowser控件甚至没有显示出来。我认为从图形对象中呈现它应该是可行的,无论图像是否在视图中。我需要进行一些实验。 - toby
我使用渲染器来处理完整页面或大型HTML表格。在那里,我需要滚动。 - Matthias Alleweldt
在我的情况下,由于安全原因,我的图像URL被拒绝访问。我可以通过webrequest获取一般的HTML页面,但无法获取图像URL。 - JHK

2
首先,我认为您获取的img元素大小与实际图像大小不同。
其次,为什么不直接使用System.Net.WebRequest并从URL下载实际图像呢?您已经有了URL和IMG元素信息。事实上,如果您不显示webbrowser,请尝试使用System.Net.WebRequest,这样您就可以验证获取的内容类型是否为实际图像或占位符。 http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx

1
我宁愿不再下载图片,因为它已经在WebControl中加载了。也许我可以从缓存中获取它?如果其他方法都失败了,我将使用WebRequest再次下载它。谢谢。 - toby
在我的情况下,可能是出于安全原因,Web请求访问图像URL被拒绝。我可以从Web请求获取一般的HTML页面,但无法获取图像URL。 - JHK

1

如果您有地址,可以使用以下方式保存:

client.DownloadFile

当客户端是一个 System.Net.WebClient


在我的情况下,可能是出于安全原因,Web请求访问图像URL被拒绝。我可以从WebRequest获取一般的HTML页面,但无法获取图像URL。 - JHK

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

你能解释一下你的代码是如何运作的吗?这将使原帖作者和其他人能够理解并在其他地方应用你的方法(如果适用)。仅有代码的回答是不被鼓励的,并且可能会被删除。- 审核期间 - Wai Ha Lee
对我来说很有效...非常感谢 - Behnam Faghih

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接