No momento, estou escrevendo um exame sobre fotografia no jogo e, ao fazê-lo, desejo (brevemente) apontar as diferenças entre uma câmera e captura de tela - mas realmente não sei o suficiente sobre o lado técnico sobre o último para fazer tão competente. Eu esperava que alguns de vocês soubessem.
Em outras palavras, como funciona a captura de tela? Ele "congela" os pixels? É a placa gráfica ou seu driver que faz o trabalho? Algum outro componente de hardware ou software?
Onde na fotografia a luz está sendo capturada por um sensor, o computador emite luz pela tela - mas estou pensando que a própria captura de tela acontece muito antes de os dados serem transformados em pixels?
Isso acontece antes que os dados sejam transformados em pixels físicos (se houver), mas acontece depois que os dados são transformados em valores de pixel , ou seja, uma imagem bitmap.
Por exemplo, se um programa está exibindo texto ou gráficos vetoriais ou visuais 3D, o processo de captura de tela não se preocupa com isso, apenas se preocupa com a imagem resultante depois que esses gráficos foram renderizados em um bitmap.
No entanto, a captura de tela é tirada diretamente da memória do sistema operacional ou, na pior das hipóteses, lida da memória da GPU – ela não é capturada dos sinais VGA ou HDMI reais.
Depende do sistema operacional que você está perguntando. Geralmente, o sistema gráfico principal (o mesmo que permite que os aplicativos coloquem janelas na tela, como GDI no Windows ou X11 no Linux) manterá uma cópia na memória de todos os pixels na tela (ou seja, o framebuffer), para que eles possam ser enviado para a GPU novamente sempre que necessário. Portanto, ele simplesmente fornece funções para que os programas recuperem essa cópia.
Por exemplo, no Windows existem as funções GetDC() e GetWindowDC() . No Linux, o sistema X11 possui métodos um tanto semelhantes, como XGetImage() . Eles apenas fornecem ao programa uma imagem de bitmap que já está armazenada em algum lugar na RAM do sistema, sem nenhum envolvimento especial de hardware.
(Embora em alguns casos, por exemplo, com o GNOME no Linux, o gerenciador de janelas na verdade usa a GPU para compor o conteúdo da tela - então, para fazer uma captura de tela, ele precisa primeiro solicitar os dados de volta à CPU.)
Como observação, pode haver algumas diferenças entre o que está no framebuffer e o que realmente está sendo exibido. Por exemplo, muitos videogames produzirão capturas de tela muito escuras porque usam o recurso de correção gama da GPU para ajustar o brilho da imagem, e essa correção é aplicada apenas como último passo ao produzir o sinal de vídeo - portanto, as capturas de tela capturarão apenas o escuro não corrigido -imagem de aparência. (A menos que o jogo realmente substitua toda a função de captura de tela do sistema operacional por conta própria.)
Uma maneira de olhar para a diferença é considerar os resultados dos dois.
Uma captura de tela é o equivalente a um computador tirando uma imagem em tela cheia em formato digital e salvando-a como um arquivo. Dessa forma, as informações digitais são tão precisas quanto possível, com base na capacidade do monitor e do adaptador de vídeo. Se você tiver um cartão e um monitor compatíveis com 4K, sua captura de tela será 4K com detalhes perfeitos.
Um instantâneo de câmera de uma tela, por outro lado, é uma conversão de digital para analógico para digital. O primeiro digital é a informação acima mencionada vinda do adaptador de vídeo. A parte analógica é a transmissão de luz da tela para os olhos e/ou câmera, enquanto a digital final é a conversão dessa luz para digital por meio do sensor digital da câmera.
Haverá uma diferença substancial na qualidade da imagem fornecida pela câmera em comparação com a captura de tela. A câmera agrega ainda mais redução de qualidade ao passar o “sinal” em forma de luz por lentes com aberrações e perdas.
Uma câmera lê dados de um sensor de luz e armazena esses dados na RAM ou em outro armazenamento. No caso de uma câmera de vídeo em vez de uma câmera fixa, ela faz isso continuamente. Os dados "brutos" do sensor podem não ser compatíveis com o formato necessário para um dispositivo de exibição, como uma placa gráfica de PC ou o LCD de uma câmera, portanto, se o dispositivo com uma câmera precisar exibir o que a câmera está vendo, é necessária uma conversão do formato da câmera para o formato do dispositivo de exibição.
Uma captura de tela é uma exportação de dados que já existem na RAM sendo usados por uma placa de vídeo ou eventualmente destinados a um dispositivo de exibição. Normalmente, esses dados estão no formato esperado por uma placa gráfica de PC ou outro dispositivo de exibição. Quando é capturado, deve ser convertido deste formato para um formato de imagem conhecido.
Portanto, as principais diferenças são de fluxo de dados:
Câmera -> dados RAW -> captura (copiar) para armazenamento ou RAM -> formato binário do dispositivo de exibição -> RAM de vídeo do dispositivo de exibição -> dispositivo de exibição (se o que a câmera está vendo deve ser exibido diretamente)
Câmera -> dados RAW -> captura (copiar) para armazenamento temporário ou RAM -> converter de lá para JPEG, etc. (se o que a câmera está vendo deve ser salvo em arquivo)
Dispositivo de exibição -> RAM de vídeo do dispositivo de exibição -> formato binário do dispositivo de exibição -> captura (copia) para outro RAM do sistema -> converte de lá para BMP, JPEG, etc. (salvando qual dispositivo de exibição está usando para gerar a imagem em arquivo)
Prefácio: Esta resposta não pretende responder totalmente à pergunta (as respostas existentes fazem isso muito bem), mas é apenas um pano de fundo conceitual que é muito longo para um comentário.
Uma grande parte da engenharia de software se resume a projetar boas abstrações, limites do sistema e dividir grandes problemas em módulos simples menores que se compõem para formar a solução total. Este é um exemplo perfeito disso em ação.
Os sistemas operacionais têm dois componentes amplos em jogo aqui: algum tipo de renderizador de GUI e algum tipo de mecanismo de saída que faz interface com ele. Embora os detalhes de implementação possam diferir, conceitualmente é muito simples. Uma tela de vídeo é apenas um tipo de dispositivo de saída, provavelmente o mais comum, mas não o único.
Um cliente de área de trabalho remota é outro. Por exemplo, o recurso de área de trabalho remota do Windows permite que você faça login em uma sessão em um computador, mesmo quando alguém estiver fisicamente usando o computador para outra sessão. Os gráficos da sua sessão são transmitidos para sua máquina pela rede, enquanto os gráficos da sessão do outro usuário são exibidos no monitor normalmente.
Salvar em um arquivo (produzindo uma captura de tela) é apenas outro tipo de dispositivo de saída.
A beleza aqui é que não precisa haver nenhum sistema separado para renderizar GUIs para capturas de tela, pois existem GUIs para renderizar a tela. A mesma renderização pode ser usada, mas é feita a interface com diferentes sistemas de saída (tela de hardware/RDP/captura de tela/gravador de tela).
O ideal é que a interface para sistemas como este seja o mais genérica possível, para que seja simples, e para que qualquer implementação possa vir e se plugar, sem muita complexidade.
No entanto, há momentos em que complicar a interface pode compensar, porque permite que você faça mais coisas de nicho. Por exemplo:
O RDP do Windows não consome apenas a saída de vídeo da tela e a transmite como se fosse uma transmissão ao vivo do Twitch. Isso usa muita largura de banda, envia muitos dados redundantes e tem maior latência. Em vez disso, o RDP transmite comandos de desenho (por exemplo, escreva o texto "Hello World!" em px 200, 200, em 12 pt Helvetica), que o cliente usa para reproduzir a GUI. Portanto, deve haver um mecanismo especial para interceptar as chamadas de desenho da GUI antes de serem enviadas para a placa gráfica para renderização como de costume (para uma tela de hardware).
O recurso de captura de tela do macOS permite que você capture uma janela, mesmo que esteja ocluída por outra janela ou tenha transparência que mostre o que está por baixo. A captura de tela resultante não será ocultada (você pode vê-la inteira) e não mostrará o que está por baixo da transparência. Isso nos diz que há algum componente do sistema de renderização da GUI que permite que o sistema de captura de tela intercepte a saída renderizada de uma única janela, antes de ser composta com as outras para formar o quadro final da tela inteira.
Uma coisa que ainda não mencionei é que "capturas de tela" nem sempre são instantâneos do quadro atual ou capturas de uma "tela".
Veja bem, as resoluções modernas exigem que grandes quantidades de dados de pixel sejam transferidas do processador gráfico (GPU) para o monitor muitas vezes por segundo. Tanto o software quanto o hardware evoluíram para não transferir informações repetidas, portanto, em particular, os pixels renderizados pela GPU são enviados apenas para o monitor, não para a CPU, a menos que solicitado.
Uma consequência disso é que, para uma captura de tela, os dados de pixel geralmente precisam ser "reconstruídos" e, no mínimo, enviados de volta da GPU para a CPU, o que pode levar um tempo considerável a partir do momento em que você pressiona o botão PrtScrn.
Ainda assim, as GPUs mais recentes geralmente podem reconstruir e enviar dados de um quadro recente para a CPU, mesmo sob carga pesada, mas uma consequência disso é que a captura de tela pode estar um pouco desatualizada. Você notará esse atraso ainda mais quando tentar transmitir/gravar, pode demorar mais de um segundo em alguns hardwares.
Mais uma vez, as razões para isso são um excesso de informações; Os milhões de pixels na GPU primeiro devem ser reconstruídos/convertidos/compactados/o que quer que seja antes de serem transferidos para a CPU em uma velocidade razoável e em um formato que a CPU possa entender.
Lembre-se de que tanto a CPU quanto a GPU precisam se comunicar e gastar tempo esperando uma pela outra enquanto fazem isso, e também precisam fazer outras coisas nesse meio tempo.
Já passamos da era de enviar dados de pixel diretamente para o monitor, ou mesmo de ter que nos preocupar em enviar dados de pixel (o software hoje está enviando texturas/modelos/triângulos, que podem transmitir a mesma imagem com muito menos informações ). Estamos acostumados com janelas múltiplas/móveis/sobrepostas/transparentes, mas na verdade existem muitos sistemas complicados que permitem que isso aconteça, cada um dos quais pode ter sua própria maneira de obter uma "captura de tela" com vários níveis de detalhe. Conheço pelo menos 4 maneiras de obter capturas de tela em minha máquina Linux, cada uma com suas próprias vantagens e desvantagens. E o mais importante, NENHUM desses métodos realmente garante que eles capturem exatamente o que foi exibido na tela.
Alguns sistemas podem capturar imagens de janelas normais sem demora, mas não de jogos ou quando sob alta carga, alguns sistemas podem solicitar capturas de tela da GPU a cada quadro, para que você possa obter a captura de tela perfeita que deseja, mesmo quando o que você estava capturando foi ocluído, alguns podem apenas janelas de "captura de tela" uma de cada vez, enquanto outras não oferecem suporte a capturas de tela em tempo real.
Nenhum sistema é igual, mas a única coisa que todo mecanismo de captura de tela tem em comum é que ele precisa se preocupar em receber 1920x1080 (ou mais!) pixels e convertê-los em um arquivo de imagem sem travar o computador inteiro. Para isso, é necessário fazer concessões com as quais as câmeras não precisam lidar.