web-dev-qa-db-ja.com

スクリーンショットはどのように機能しますか?

私は現在、ゲーム内の写真について試験問題を書いています。そのため、カメラとスクリーンショットの違いを(簡単に)指摘したいと思います。ただし、後者の技術的な側面については、十分な知識がありません。とても有能。皆さんが知っていることを望んでいましたか?

言い換えれば、スクリーンショットはどのように機能しますか?ピクセルを「フリーズ」しますか?機能するのはグラフィックカードまたはそのドライバーですか?他のハードウェアまたはソフトウェアコンポーネント?

写真の場合、光はセンサーによって取り込まれ、コンピューターは代わりに画面を通して光を放射しますが、データがピクセルに変換される前にスクリーンショット自体が発生すると思いますか?

12
Erica Wyrdling

しかし、データがピクセルに変換される前にスクリーンショット自体が発生すると思いますか?

これは、データがphysicalピクセル(存在する場合)に変換される前に発生しますが、データがpixel valuesに変換された後に発生します(ビットマップイメージなど)。

たとえば、プログラムがテキストまたはベクターグラフィックスまたは3Dビジュアルを表示している場合、スクリーンショットプロセスはそれをまったく考慮せず、グラフィックがビットマップにレンダリングされた後の結果のイメージのみを考慮します。

ただし、スクリーンショットはOSメモリから直接取得されるか、最悪の場合、GPUメモリから読み戻されます。実際のVGAまたはHDMI信号からキャプチャされますnot

言い換えれば、スクリーンショットはどのように機能しますか?ピクセルを「フリーズ」しますか?機能するのはグラフィックカードまたはそのドライバーですか?他のハードウェアまたはソフトウェアコンポーネント?

あなたが尋ねているOSに依存します。一般に、コアグラフィックシステム(GDI、LinuxではX11など)が画面にウィンドウを配置できる同じシステム)は、画面上のすべてのピクセルのメモリ内コピーを保持します(つまり、フレームバッファ)を使用して、必要に応じて再度GPUに送信できるようにするため、プログラムがそのコピーを取得するための関数を提供します。

たとえば、Windowsには GetDC() および GetWindowDC() 関数があります。 Linuxでは、X11システムには XGetImage() などの類似したメソッドがいくつかあります。これらは、特別なハードウェアの関与なしに、システムRAMのどこかに既に保持されているビットマップイメージをプログラムに提供するだけです。

(Linux上のGNOMEなど一部のケースではありますが、ウィンドウマネージャーは実際にGPUを使用して画面のコンテンツを作成します。したがって、スクリーンショットを作成するには、最初にCPUにデータを要求する必要があります。)


補足として、フレームバッファの内容と実際に表示されている内容にはいくつかの違いがあります。たとえば、多くのビデオゲームでは、GPUのガンマ補正機能を使用して画像の明るさを調整するため、非常に暗いスクリーンショットが生成されます。この補正は、ビデオ信号を生成するときの最後のステップとしてのみ適用されるため、スクリーンショット修正されていない暗い画像のみをキャプチャします。 (ゲームが実際にOSスクリーンショット機能全体を独自のものでオーバーライドしない限り)

16
user1686

違いを見る1つの方法は、2つの結果を検討することです。

スクリーンショットは、フルスクリーン画像をデジタル形式で取得してファイルとして保存するコンピューターと同じです。このように、デジタル情報は、モニターとディスプレイアダプターの機能に基づいて、可能な限り正確です。 4K対応のカードとディスプレイを使用している場合、画面キャプチャは4Kになります。

一方、画面のカメラスナップショットは、デジタルからアナログへのデジタル変換です。最初のデジタルは、ディスプレイアダプターからの前述の情報です。アナログ部分はディスプレイから目やカメラへの光の透過であり、最後のデジタルはカメラのデジタルセンサーを介してその光をデジタルに変換することです。

画面キャプチャと比較して、カメラによって提供される画像の品質には大きな違いがあります。このカメラは、収差と損失を伴うレンズを通して光の形で「信号」を通過させることにより、品質をさらに低下させます。

2
fred_dot_u

序文:この回答は質問に完全に回答することを意図したものではありません(既存の回答はそれで十分です)が、コメントには長すぎる概念的な背景にすぎません。

ソフトウェアエンジニアリングの大部分は、優れた抽象化、システム境界を設計し、大きな問題をより小さな単純なモジュールに分解して、全体のソリューションを形成することです。これは、その実際の例です。

ここでは、オペレーティングシステムに2つの広範なコンポーネントが関係しています。ある種のGUIレンダラーと、それとやり取りするある種の出力メカニズムです。実装の詳細は異なる場合がありますが、概念的には非常に簡単です。ビデオ画面は1種類の出力デバイスであり、おそらく最も一般的なものですが、唯一のものではありません。

リモートデスクトップクライアントは別です。たとえば、Windowsのリモートデスクトップ機能を使用すると、コンピューターを別のセッションで物理的に使用しているときでも、コンピューターのセッションにログインできます。セッションのグラフィックはネットワーク経由でマシンにストリーミングされ、他のユーザーのセッションのグラフィックは通常どおりモニターに表示されます。

ファイルへの保存(スクリーンショットの生成)は、もう1つの種類の出力デバイスです。

ここでの美しさは、スクリーンショット用のGUIをレンダリングする場合のように、スクリーンショット用のGUIをレンダリングするための個別のシステムが必要ないことです。同じレンダリングを使用できますが、異なる出力システム(ハードウェア画面/ RDP /スクリーンショット/スクリーンレコーダー)とインターフェイスします。

理想的には、このようなシステムのインターフェースは可能な限り汎用的である必要があります。これは、それが単純であり、どんな実装も、それほど複雑にすることなく、それ自体をプラグインできるようにするためです。

ただし、よりニッチなことを実行できるため、インターフェースを複雑にすることで成果が得られる場合があります。例えば:

  • WindowsのRDPは、画面のビデオ出力を消費してTwitchライブストリームであるかのようにストリーミングするだけではありません。これは、帯域幅を使いすぎ、冗長なデータを送りすぎ、待ち時間が長くなります。代わりに、RDPはクライアントがGUIを再現するために使用する描画コマンドを介して送信します(たとえば、テキスト「Hello World!」をピクセル200、200で12 pt Helveticaに書き込みます)。したがって、通常のように(ハードウェア画面に)レンダリングするためにグラフィックスカードに送信される前に、GUI描画呼び出しをインターセプトする特別なメカニズムが必要です。

    • これは、ビデオ出力をストリーミングするだけのVNCとは対照的です。これには、前述のパフォーマンスの短所がありますが、重要な利点があります。インターフェースがよりシンプル/より汎用的であるため、より多くの実装がこれに準拠できます。 VNCは、OSごとの特定のGUI描画コマンドに関連付けられていないため、Windowsだけでなく、より多くのオペレーティングシステムによって、より広範囲に実装されています。
  • macOSのスクリーンショットキャプチャ機能を使用すると、別のウィンドウで遮られていたり、下に何が表示されている場合でも、ウィンドウのスクリーンショットを撮ることができます。結果のスクリーンショットは隠されず(全体を見ることができます)、透明度の下にあるものは表示されません。これは、スクリーンショットシステムが他のウィンドウと合成されて全画面の最終フレームを形成する前に、スクリーンショットシステムが単一のウィンドウのレンダリング出力をインターセプトできるようにするGUIレンダリングシステムのコンポーネントがあることを示しています。

カメラは光センサーからデータを読み取り、そのデータをRAM=または他のストレージに保存します。静止カメラとは対照的に、ビデオカメラの場合は、これを継続的に実行しています。センサーからのデータは、PCグラフィックカードやカメラのLCDなどのディスプレイデバイスが必要とするフォーマットと互換性がない可能性があるため、カメラを備えたデバイスが何を表示する必要があるかカメラが認識している場合、カメラ形式からディスプレイデバイス形式への変換が必要です。

スクリーンショットは、RAMビデオカードで使用されている、または最終的にはディスプレイデバイスに送信される)に既に存在するデータのエクスポートです。通常、このデータは、PCグラフィックカードまたはその他のディスプレイデバイスの形式です。キャプチャされたら、この形式から既知の画像形式に変換する必要があります。

したがって、主な違いはデータフローの1つです。

カメラ-> RAWデータ->ストレージへのキャプチャ(コピー)またはRAM->表示デバイスのバイナリ形式->表示デバイスのビデオRAM->表示デバイス(カメラが見ているものを直接表示する場合)

カメラ-> RAWデータ->一時ストレージへのキャプチャ(コピー)またはRAM->そこからJPEGへの変換など(カメラが表示しているものをファイルに保存する必要がある場合)

ディスプレイデバイス->ディスプレイデバイスビデオRAM->ディスプレイデバイスバイナリフォーマット->他のシステムへのキャプチャ(コピー)RAM->そこからBMPに変換し、 JPEGなど(画像をファイルに生成するために使用しているディスプレイデバイスの保存)

2
LawrenceC

私がまだ言及していないことの1つは、「スクリーンショット」は必ずしも現在のフレームのスナップショット、または「スクリーン」のキャプチャーではないということです。

ご覧のとおり、最新の解像度では、グラフィックプロセッサ(GPU)からモニターに1秒に何回も大量のピクセルデータを転送する必要があります。ソフトウェアとハ​​ードウェアの両方が繰り返される情報を転送しないように進化しているため、特にGPUによってレンダリングされたピクセルは、要求されない限り、CPUではなくモニターにのみ送信されます。

これの1つの結果は、スクリーンショットの場合、ピクセルデータを「再構築」する必要があることが多く、少なくとも、GPUからCPUにピクセルデータを送り返す必要があることです。どちらも、押した瞬間からかなりの時間がかかる場合があります。 PrtScrnボタン。

それでも、新しいGPUは、負荷が高い場合でも、最近のフレームからCPUにデータを再構築して送信できることがよくありますが、その結果、スクリーンショットが少し古い可能性があります。ストリーミング/録音しようとすると、この遅延にさらに気付くでしょう。ハードウェアによっては、1秒以上かかる場合があります。

繰り返しますが、これの理由は情報のオーバーフローです。 GPU上の何百万ものピクセルは、妥当な速度で、CPUが理解できる形式でCPUに転送される前に、最初に再構築/変換/圧縮/何でもする必要があります。

CPUとGPUの両方が通信し、これを実行している間、互いを待つ時間を費やす必要があり、その間に他のことも行う必要があることを覚えておいてください。

ピクセルデータを直接モニターに送信する時代、またはピクセルデータを送信することをまったく気にする必要がない時代から、私たちはずっと昔に(今日のソフトウェアは、代わりにテクスチャ/モデル/三角形を送信しているため、同じ情報をはるかに少ない情報で伝えることができます) )。複数/移動可能/重複可能/透明なウィンドウに慣れていますが、実際にはこれを可能にする多くの複雑なシステムがあり、それぞれにさまざまな詳細レベルの「スクリーンショット」を取得する独自の方法がある場合があります。 Linuxマシンでスクリーンショットを取得するには、少なくとも4つの方法があります。それぞれに独自の利点と欠点があります。そして重要なのは、これらのメソッドのどれもが実際に画面に表示されたものを正確にキャプチャすることを保証しないことです。

一部のシステムでは、通常のウィンドウを遅延なしでスクリーンショットできますが、ゲームや高負荷の場合、フレームごとにGPUからスクリーンショットを要求する場合があるため、キャプチャしているものが隠れていたとしても、必要な完璧なスクリーンショットを取得できます。 「スクリーンショット」ウィンドウは一度に1つだけですが、リアルタイムスクリーンショットをサポートしていないウィンドウもあります。

どのシステムも同じではありませんが、すべてのスクリーンショットメカニズムに共通しているのは、1920x1080(またはそれ以上)のピクセルを受け取り、コンピューター全体をロックすることなくそれらを画像ファイルに変換することについて心配する必要があることです。そのためには、カメラが対処する必要のない妥協が必要です。

0
yyny