2011-05-05 12 views
5

Se ejecuta el siguiente código, pero el mapa de bits generado se desplaza hacia abajo aproximadamente media pulgada y el límite en la parte inferior. Comprobé el ancho y el alto de la imagen y está creando una imagen del tamaño correcto, solo el contenido de la imagen se desplaza hacia abajo y se corta. Estoy perplejo ... ¿Alguna idea?Guardar imágenes desde un control WebBrowser

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; 
    } 

Respuesta

3

Lo que está haciendo es hacer que la imagen tal y como se representa por el navegador con todos los estilos. No sé si esto es lo que realmente quieres? Si solo desea descargar la imagen, entonces es más fácil resolverla con una solicitud web como se describe en otras respuestas.

Si realmente quiere hacer que el primer paso es cambiar

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

a

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

ya que usted consigue la imagen navegador web prestado completa.

Si quieres una solución perfecta incluso para imágenes grandes, también tienes que desplazarte por la imagen y obtener la imagen por mosaico.

+0

¿Sería realmente necesario el desplazamiento para imágenes grandes? Mi control WebBrowser ni siquiera es visible. Pensaría que renderizarlo desde el objeto gráfico funcionaría tanto si la imagen está a la vista como si no. Voy a necesitar experimentar con eso. – toby

+0

Utilizo el procesador para páginas completas o grandes tablas HTML. Ahí tengo que desplazarme. –

2

para empezar Creo que el elemento img que se obtiene tiene un tamaño diferente a lo que es el tamaño real de la imagen.

En segundo lugar, ¿por qué no usa System.Net.WebRequest directo y descarga la imagen real de la URL. ya tiene la URL y ya tiene la información del elemento IMG; de hecho, si no muestra el navegador web, intente con System.Net.WebRequest, de esta manera puede verificar qué tipo de contenido obtiene si es una imagen real o titular de lugar.

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

+1

Preferiría no volver a descargar la imagen porque ya está cargada en WebControl. Tal vez puedo obtenerlo del caché? Si todo lo demás falla, usaré una WebRequest y la descargaré de nuevo. Gracias. – toby

1

Si tiene la dirección, puede guardarlo usando:

client.DownloadFile 

Cuando el cliente es un System.Net.WebClient

-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 
+0

¿Podría explicar cómo y por qué funciona su código? Eso permitirá que OP y otros entiendan y apliquen sus métodos (donde corresponda) en cualquier otro lugar. Las respuestas de solo código son [desaconsejadas] (http://meta.stackexchange.com/q/148272/284827) y pueden ser eliminadas. - [Durante la revisión] (http://stackoverflow.com/review/late-answers/11706009) –

Cuestiones relacionadas