2010-11-09 24 views
7

Como proyecto de hobby, estoy explorando las formas de guardar una página web (HTML) como imagen, principalmente programáticamente usando c/C++/javascript/java. Hasta ahora me he encontrado las siguientes maneras:Guardar una página web como imagen

  1. Consigue el IHTMLElement del cuerpo de la página y lo utilizan para consultar IHTMLElementRender y luego usar su método DrawToDC (Ref:http://www.codeproject.com/KB/IP/htmlimagecapture.aspx). Pero el problema es que no funcionó para todas las páginas (en su mayoría páginas con iframes incrustados).

  2. Otra forma lo que se me ocurre es utilizar algún componente navegador web y cuando las páginas se ha cargado completamente y luego capturarlo usando BitBlt (Ref:http://msdn.microsoft.com/en-us/library/dd183370%28VS.85%29.aspx). Pero el problema es que la página que he solicitado puede ser más larga que el tamaño de mi pantalla y no cabe en el componente del navegador web.

Cualquier dirección/sugerencia para resolver los problemas anteriores o un enfoque alternativo es muy apreciada.

Respuesta

1

Bueno, finalmente capaz de romper por ir a través de estos dos artículos:

  1. http://www.codeproject.com/KB/GDI-plus/WebPageSnapshot.aspx [C# de código - IE]
  2. http://www.codeproject.com/KB/graphics/IECapture.aspx [C++ & GDI - IE]

Pueden' t compartir el código, pero los dos artículos anteriores le brindarán la mejor solución posible.

también echar un vistazo a:

https://addons.mozilla.org/en-US/firefox/addon/3408/ [Firefox + Javascript]

Por encima de las cosas son todavía bien. PERO no se garantiza que funcione siempre. Compruebe el siguiente enlace: How do I render the scrollable regions of a canvas with IViewObject::Draw?

1

Si usa Python, está pywebshot y webkit2png. Ambos tienen algunas dependencias, sin embargo.

Editar: Vaya, Python no está en su lista de idiomas preferidos. Dejaré esta respuesta aquí de todos modos, porque dijiste "principalmente" y no "exclusivamente".

+0

Gracias Kijin .. he considerado, pero con el fin de úselo Tengo que aprender Python :) – Favonius

1

Otra opción (algo indirecta) sería ejecutar un servidor como Tomcat y usar Java para llamar a una herramienta de línea de comandos para tomar una captura de pantalla. Buscar en Google para "ventanas de captura de pantalla de línea de comando" ofrece algunas posibilidades de aspecto razonable. Además de ejecutar un servidor, no sé una buena manera de ejecutar ejecutables locales desde JavaScript. Sin embargo, este método lo convertiría en un navegador cruzado, lo cual es una ventaja (solo haga una llamada ajax al script cuando desee una captura de pantalla).

Lamentablemente, no sé cómo implementar archivos de guerra. Puede ser más problemático usar Tomcat; Lo mencioné porque Java era un idioma preferido. Sería bastante fácil de ejecutar XAMPP y el uso de este fragmento de PHP, y no sería realmente tiene que aprender php:

<?php 
exec("/path/to/exec args"); 
?> 

EDITAR

Ya sabes, no estoy seguro de que realmente respuestas tu pregunta. Es de una manera, pero está llegando desde el extremo de JavaScript en lugar del final de scripting. Si quieres hacerlo a través de scripts, siempre puedes usar Selenium. Es compatible con la captura de capturas de pantalla de una página completa, y se puede controlar a través de Java.

+0

Gracias, ¿podrían explicar el uso de tomcat y java aquí? Digamos que quiero acceder a http://stackoverflow.com, ¿dónde encajará la pieza de Tomcat? El selenio es una buena opción, lo investigará. – Favonius

+0

En realidad, no sé qué tan involucrado es implementar una aplicación web en Tomcat. Sería más fácil simplemente usar XAMPP y un fragmento de PHP. Editado mi respuesta. – theazureshadow

0

Si estás bien usando javascript para ello, le sugiero ir con phantomjs

Ejemplo de http://fcargoet.evolix.net/

var page = new WebPage(), 
    address = 'http://dev.sencha.com/deploy/ext-4.0.7-gpl/examples/feed-viewer/feed-viewer.html'; 

page.viewportSize = { 
    width : 800, 
    height : 600 
}; 

// define the components we want to capture 
var components = [{ 
    output : 'feed-viewer-left.png', 
    //ExtJS has a nice component query engine 
    selector : 'feedpanel' 
},{ 
    output : 'feed-viewer-preview-btn.png', 
    selector : 'feeddetail > feedgrid > toolbar > cycle' 
},{ 
    output : 'feed-viewer-collapsed.png', 
    //executed before the rendering 
    before : function(){ 
     var panel = Ext.ComponentQuery.query('feedpanel')[0]; 
     panel.animCollapse = false; // cancel animation, no need to wait before capture 
     panel.collapse(); 
    }, 
    selector : 'viewport' 
}]; 

page.open(address, function (status) { 
    if (status !== 'success') { 
     console.log('Unable to load the address!'); 
    } else { 
     /* 
     * give some time to ExtJS to 
     * - render the application 
     * - load asynchronous data 
     */ 
     window.setTimeout(function() { 
      components.forEach(function(component){ 
       //execute the before function 
       component.before && page.evaluate(component.before); 
       // get the rectangular area to capture 
       /* 
       * page.evaluate() is sandboxed 
       * so that 'component' is not defined. 
       * 
       * It should be possible to pass variables in phantomjs 1.5 
       * but for now, workaround! 
       */ 
       eval('function workaround(){ window.componentSelector = "' + component.selector + '";}') 
       page.evaluate(workaround); 

       var rect = page.evaluate(function(){ 
        // find the component 
        var comp = Ext.ComponentQuery.query(window.componentSelector)[0]; 
        // get its bounding box 
        var box = comp.el.getBox(); 
        // box is {x, y, width, height} 
        // we want {top, left, width, height} 
        box.top = box.y; 
        box.left = box.x; 
        return box; 
       }); 
       page.clipRect = rect; 
       page.render(component.output); 
      }); 
      // job done, exit 
      phantom.exit(); 
     }, 2000); 
    } 
}); 
Cuestiones relacionadas