プログラムで画面の明るさを変更する機能を調査しているときに、この記事に出くわしました。プログラムで画面の明るさを変更する-GamaRampAPIを使用します。
デバッガーを使用して、GetDeviceGamaRamp()
関数によって提供される値を確認しました。出力は、のようなものとして定義された2次元配列WORD GammaArray[3][256];
であり、表示されたピクセルの赤、緑、および青の値を変更するための256個の値のテーブルです。私が見た値は、インデックス0でゼロ(0)の値から始まり、次の値を計算するために256の値を追加しました。したがって、インデックス0、1、2、...、254、255の場合、シーケンスは0、256、512、...、65024、65280になります。
私の理解では、これらの値は各ピクセルのRGB値を変更するために使用されます。テーブルの値を変更することにより、ディスプレイの明るさを変更できます。ただし、この手法の効果は、ディスプレイのハードウェアによって異なる場合があります。
Direct3Dの観点からではありますが、ガンマランプレベルについて説明しているこの短い記事、ガンマコントロールが興味深いと思われるかもしれません。この記事には、ガンマランプレベルについての説明があります。
Direct3Dでは、ガンマランプという用語は、フレームバッファ内のすべてのピクセルの特定の色成分(赤、緑、青)のレベルを、DACが表示用に受信する新しいレベルにマッピングする一連の値を表します。再マッピングは、カラーコンポーネントごとに1つずつ、3つのルックアップテーブルを使用して実行されます。
仕組みは次のとおりです。Direct3Dはフレームバッファからピクセルを取得し、個々の赤、緑、青の色成分を評価します。各コンポーネントは、0〜65535の値で表されます。Direct3Dは元の値を取得し、それを使用して256要素の配列(ランプ)にインデックスを付けます。各要素には、元の値を置き換える値が含まれます。Direct3Dは、フレームバッファー内の各ピクセルの各カラーコンポーネントに対してこのルックアップおよび置換プロセスを実行し、それによって画面上のすべてのピクセルの最終的なカラーを変更します。
のオンラインドキュメントによるとGetDeviceGamaRamp()
、SetDeviceGamaRamp()
これらの関数はWindows2000Professional以降のWindowsAPIでサポートされています。
Windowsアプリケーションに挿入された次の例に要約されたソースを使用して、参照記事の値を使用して効果をテストしました。私のテストは、Windows7とAMDRadeonHD7450グラフィックスアダプターを使用して行われました。
このテストでは、2つのディスプレイがあり、両方のディスプレイが影響を受けました。
//Generate the 256-colors array for the specified wBrightness value.
WORD GammaArray[3][256];
HDC hGammaDC = ::GetDC(NULL);
WORD wBrightness;
::GetDeviceGammaRamp (hGammaDC, GammaArray);
wBrightness = 64; // reduce the brightness
for (int ik = 0; ik < 256; ik++) {
int iArrayValue = ik * (wBrightness + 128);
if (iArrayValue > 0xffff) iArrayValue = 0xffff;
GammaArray[0][ik] = (WORD)iArrayValue;
GammaArray[1][ik] = (WORD)iArrayValue;
GammaArray[2][ik] = (WORD)iArrayValue;
}
::SetDeviceGammaRamp (hGammaDC, GammaArray);
Sleep (3000);
wBrightness = 128; // set the brightness back to normal
for (int ik = 0; ik < 256; ik++) {
int iArrayValue = ik * (wBrightness + 128);
if (iArrayValue > 0xffff) iArrayValue = 0xffff;
GammaArray[0][ik] = (WORD)iArrayValue;
GammaArray[1][ik] = (WORD)iArrayValue;
GammaArray[2][ik] = (WORD)iArrayValue;
}
::SetDeviceGammaRamp (hGammaDC, GammaArray);
Sleep (3000);
::ReleaseDC(NULL, hGammaDC);
追記として、上記のソースにわずかな変更を加えて、各RGB値を均等に変更するのではなく、最初の2つの割り当てをコメントアウトしてGammaArray[2][ik]
変更のみにしました。その結果、ディスプレイに黄色がかったキャストが表示されました。
また、上記のソースをループに入れて、表示がどのように変化したかを確認してみましたが、とはかなり違いましwBrightness=0
たwBrightness=128
。
for (wBrightness = 0; wBrightness <= 128; wBrightness += 16) {
for (int ik = 0; ik < 256; ik++) {
int iArrayValue = ik * (wBrightness + 128);
if (iArrayValue > 0xffff) iArrayValue = 0xffff;
GammaArray[0][ik] = (WORD)iArrayValue;
GammaArray[1][ik] = (WORD)iArrayValue;
GammaArray[2][ik] = (WORD)iArrayValue;
}
::SetDeviceGammaRamp (hGammaDC, GammaArray);
Sleep (3000);
}
Microsoftは、ガンマ補正の使用に関するオンラインのMSDN記事を提供しています。これは、ガンマの基本を次のように説明しているDirect3Dドキュメントの一部です。
グラフィックスパイプラインの最後、つまり画像がコンピューターを離れてモニターケーブルに沿って移動する場所に、ピクセル値をその場で変換できる小さなハードウェアがあります。このハードウェアは通常、ルックアップテーブルを使用してピクセルを変換します。このハードウェアは、表示される表面からの赤、緑、青の値を使用して、テーブル内のガンマ補正値を検索し、実際の表面値の代わりに補正値をモニターに送信します。したがって、このルックアップテーブルは、任意の色を他の色に置き換える機会です。テーブルにはそのレベルのパワーがありますが、一般的な使用法は、モニターの応答の違いを補正するために画像を微調整することです。モニターの応答は、赤の数値を関連付ける関数です。
さらに、ソフトウェアアプリケーションRedshiftには、 MicrosoftWindowsについて言うことができるページWindowsガンマ調整があります。
RedshiftをWindowsに移植するときに、色温度を約4500Kより低く設定すると問題が発生しました。問題は、Windowsが、実行できるガンマ調整の種類に制限を設定していることです。おそらく、色を反転したり、ディスプレイを空白にしたり、ガンマランプで他の厄介なトリックを実行したりする邪悪なプログラムからユーザーを保護する手段としてです。この種の制限はおそらく理解できますが、問題はこの機能のドキュメントが完全に不足していることです(MSDNのSetDeviceGammaRamp)。許可されていないガンマランプを設定しようとするプログラムは、一般的なエラーで失敗し、プログラマーは何が悪かったのか疑問に思います。