Tirar uma captura de tela de uma página da Web com JavaScript?

148

É possível tirar uma captura de tela de uma página da Web com JavaScript e enviá-la de volta ao servidor?

Não estou tão preocupado com problemas de segurança do navegador. etc. como a implementação seria para o HTA . Mas isso é possível?

Scott Bennett-McLeish
fonte
Você pode esclarecer por que deseja fazer isso? Talvez haja soluções alternativas para tirar screenshots.
andyuk 13/09/08
Eu estou olhando para ter o usuário projetar aproximadamente o que eles querem, um esboço e um arrastar e soltar objetos. Desejo que esse "design" seja usado como parte das instruções em um processo de produção. É definitivamente um passo, nada clandestino envolvido pelo usuário aqui :)
Scott Bennett-McLeish

Respostas:

42

Eu fiz isso para um HTA usando um controle ActiveX. Foi muito fácil criar o controle no VB6 para fazer a captura de tela. Eu tive que usar a chamada da API keybd_event porque as SendKeys não podem executar o PrintScreen. Aqui está o código para isso:

Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Public Const CaptWindow = 2

Public Sub ScreenGrab()
   keybd_event &H12, 0, 0, 0
   keybd_event &H2C, CaptWindow, 0, 0
   keybd_event &H2C, CaptWindow, &H2, 0
   keybd_event &H12, 0, &H2, 0
End Sub

Isso só leva você até a janela para a área de transferência.

Outra opção, se a janela da qual você deseja uma captura de tela for um HTA, seria apenas usar um XMLHTTPRequest para enviar os nós do DOM para o servidor e criar as capturas de tela do lado do servidor.

Joel Anair
fonte
Concordo com Allen, que é uma maneira engenhosa de capturar uma página potencialmente!
Ricket 21/05/19
O que um "HTA" por favor?
Pete Alvin
2
O @PeteAlvin an HTA é um aplicativo de hipertexto, que era uma maneira de executar aplicativos JS privilegiados no Internet Explorer. Não é super relevante hoje.
Joel Anair #
141

O Google está fazendo isso no Google+ e um desenvolvedor talentoso fez a engenharia reversa e produziu http://html2canvas.hertzen.com/ . Para trabalhar no IE, você precisará de uma biblioteca de suporte de tela, como http://excanvas.sourceforge.net/

JAAulde
fonte
2
Obrigado, os links em sua postagem explicam tudo bem
Hüseyin Babal
2
Se você não quiser fazer isso por si mesmo, vale a pena tentar o Usersnap . É uma queda na solução para obter capturas de tela precisas do navegador de seus visitantes sem instalar um plug-in (e nenhum Java, ActiveX ou Flash).
22713 Gregor
você pode verificar este stackoverflow.com/questions/44494447/…
abilash er
14

Outra solução possível que descobri é o http://www.phantomjs.org/, que permite tirar facilmente capturas de tela de páginas e muito mais. Embora meus requisitos originais para esta pergunta não sejam mais válidos (trabalho diferente), provavelmente integrarei o PhantomJS em projetos futuros.

Scott Bennett-McLeish
fonte
Você sabe se os phantomjs podem gerar uma imagem de um elemento em uma página (não na página inteira)?
trusktr
Sim você pode. Use esse trecho com o PhantomJS ou o CasperJS .
Zopieux
12

Pounder, se isso é possível, definindo os elementos do corpo inteiro em uma tela, usando canvas2image?

http://www.nihilogic.dk/labs/canvas2image/

RobertPitt
fonte
maravilha se SVG iria ajudar, pode ter que olhar na fonte do Google
Luke Stanley
1
Você pode usar o código html2canvas da Niklas para renderizar html na tela e usá-lo para salvar uma imagem.
trusktr
9

Uma maneira possível de fazer isso, se você estiver executando o Windows e tiver o .NET instalado, poderá:

public Bitmap GenerateScreenshot(string url)
{
    // This method gets a screenshot of the webpage
    // rendered at its full size (height and width)
    return GenerateScreenshot(url, -1, -1);
}

public Bitmap GenerateScreenshot(string url, int width, int height)
{
    // Load the webpage into a WebBrowser control
    WebBrowser wb = new WebBrowser();
    wb.ScrollBarsEnabled = false;
    wb.ScriptErrorsSuppressed = true;
    wb.Navigate(url);
    while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }


    // Set the size of the WebBrowser control
    wb.Width = width;
    wb.Height = height;

    if (width == -1)
    {
        // Take Screenshot of the web pages full width
        wb.Width = wb.Document.Body.ScrollRectangle.Width;
    }

    if (height == -1)
    {
        // Take Screenshot of the web pages full height
        wb.Height = wb.Document.Body.ScrollRectangle.Height;
    }

    // Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
    Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
    wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
    wb.Dispose();

    return bitmap;
}

E então via PHP você pode fazer:

exec("CreateScreenShot.exe -url http://.... -save C:/shots domain_page.png");

Então você tem a captura de tela no lado do servidor.

RobertPitt
fonte
1
Embora não esteja relacionada às perguntas, essa é uma sugestão incrível! Obrigado !
Mihai
por que ele não carrega alguns estilos que até eu posso vê-los carregados no IE9 ?!
Dr TJ
7

Essa pode não ser a solução ideal para você, mas ainda vale a pena mencionar.

Snapsie é um objeto ActiveX de código aberto que permite capturar e salvar capturas de tela do Internet Explorer. Depois que o arquivo DLL estiver registrado no cliente, você poderá capturar a captura de tela e fazer upload do arquivo no servidor com JavaScript. Desvantagens: ele precisa registrar o arquivo DLL no cliente e funciona apenas com o Internet Explorer.

Nikhil
fonte
6

Tínhamos um requisito semelhante para relatar erros. Como era para um cenário de intranet, pudemos usar complementos de navegador (como Fireshot para Firefox e IE Screenshot para Internet Explorer).

Gulzar Nazim
fonte
1

Você pode conseguir isso usando HTA e VBScript . Basta ligar para uma ferramenta externa para fazer a captura de tela. Esqueci o nome, mas no Windows Vista existe uma ferramenta para fazer capturas de tela. Você nem precisa de uma instalação extra para isso.

Quanto automático - depende totalmente da ferramenta que você usa. Se houver uma API, tenho certeza de que você pode acionar a captura de tela e o processo de salvamento por meio de duas chamadas do Visual Basic sem que o usuário saiba que você fez o que fez.

Desde que você mencionou o HTA, suponho que você esteja no Windows e (provavelmente) conheça seu ambiente (por exemplo, sistema operacional e versão) muito bem.

Até
fonte
Ele está tentando fazê-lo como parte de uma aplicação web através calcula dos clientes, não para uso pessoal
mrBorna
1

Eu descobri que o dom-to-image fez um bom trabalho (muito melhor que o html2canvas). Consulte a seguinte pergunta e resposta: https://stackoverflow.com/a/32776834/207981

Esta pergunta é sobre como enviar isso de volta ao servidor, o que deve ser possível, mas se você deseja fazer o download das imagens, combine-as com o FileSaver.js e se deseja fazer o download de um zip com vários arquivos de imagem, todos gerados no lado do cliente, dão uma olhada no jszip .

bszom
fonte
0

Uma ótima solução para captura de tela em Javascript é a https://grabz.it .

Eles possuem uma API de captura de tela flexível e fácil de usar, que pode ser usada por qualquer tipo de aplicativo JS.

Se você quiser experimentá-lo, primeiro você deve obter a chave do aplicativo de autorização + segredo e o SDK gratuito

Em seu aplicativo, as etapas de implementação seriam:

// include the grabzit.min.js library in the web page you want the capture to appear
<script src="grabzit.min.js"></script>

//use the key and the secret to login, capture the url
<script>
GrabzIt("KEY", "SECRET").ConvertURL("http://www.google.com").Create();
</script>

A captura de tela pode ser personalizada com diferentes parâmetros . Por exemplo:

GrabzIt("KEY", "SECRET").ConvertURL("http://www.google.com", 
{"width": 400, "height": 400, "format": "png", "delay", 10000}).Create();
</script>

Isso é tudo. Em seguida, basta esperar um pouco e a imagem aparecerá automaticamente na parte inferior da página, sem a necessidade de recarregar a página.

Existem outras funcionalidades do mecanismo de captura de tela que você pode explorar aqui .

Também é possível salvar a captura de tela localmente. Para isso, você precisará utilizar a API do lado do servidor GrabzIt. Para mais informações, consulte o guia detalhado aqui .

Johnny
fonte
0

Se você deseja fazer isso no lado do servidor, há opções como o PhantomJS , que agora está obsoleto. O melhor caminho a seguir seria o Headless Chrome com algo como Puppeteer no Node.JS. Capturar uma página da Web usando o Puppeteer seria tão simples como a seguir:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

No entanto, exige que o chrome sem cabeça seja capaz de executar em seus servidores, o que tem algumas dependências e pode não ser adequado em ambientes restritos. (Além disso, se você não estiver usando o Node.JS, pode ser necessário cuidar da instalação / inicialização dos navegadores.)

Se você deseja usar um serviço SaaS, existem muitas opções, como

Ekin Koc
fonte
0

Atualmente, biblioteca GitHub de abril de 2020 html2Canvas https://github.com/niklasvh/html2canvas

Estrelas do GitHub 20K | Pipeles do Azure: Sucedido | Downloads 1,3M / mês |

citação: " JavaScript HTML renderer O script permite que você faça" capturas de tela "de páginas da Web ou partes dele diretamente no navegador do usuário . A captura de tela é baseada no DOM e, como tal, pode não ser 100% precisa da representação real, pois não cria uma captura de tela real, mas cria a captura de tela com base nas informações disponíveis na página.

zennni
fonte