Frage

Ich möchte die Möglichkeit hinzufügen, die Bildschirm -Gamma beim Anwendungsstart einzustellen und beim Ausgang zurückzusetzen. Es ist zwar umstritten, ob man Gamma überhaupt manipulieren sollte (persönlich finde ich es nutzlos und schädlich), aber hey, einige Leute erwarten, dass man so etwas tun kann.

Es ist auch nur ein einfacher API -Anruf, also ist alles einfach, oder?

MSDN sagt: "Die Gamma -Rampe ist in drei Arrays von 256 Wortelementen angegeben. Die Werte müssen in den bedeutendsten Bits jedes Wortes gespeichert werden, um die DAC -Unabhängigkeit zu erhöhen.". Dies bedeutet nach meinem Verständnis so etwas wie word_value = byte_value<<8, Das klingt ziemlich seltsam, aber so habe ich es gelesen.

Der Doom3 -Quellcode enthält eine Funktion, die drei Arrays von annimmt char Werte und konvertiert sie in ein Array von uint16_t Werte, die den gleichen Bytewert haben beide in der oberen und unteren Hälfte. Mit anderen Worten so etwas wie word_value = (byte_value<<8)|byte_value. Das ist ebenso seltsam, aber was schlimmer ist, ist es nicht das gleiche wie oben.

Es gibt auch einige Code -Snippets im Internet auf verschiedenen Hobby -Programmiererseiten (anscheinend einer aus dem anderen gestohlen, weil sie mit dem Buchstaben identisch sind), die einige obskure mathematische Multiplikation des linearen Index mit einem Wert, der Vorspannung mit 128, multiplizieren. Und auf 65535 zu klemmen. Ich bin mir nicht ganz sicher, worum es geht, aber es sieht für mich nach totaler Unsinn aus, und wieder ist es nicht dasselbe wie einer der beiden oben genannten.

Was gibt? Es muss gut definiert sein-ohne zu erraten-, wie die Daten, die Sie liefern, aussehen müssen? Am Ende wird man die ursprünglichen Werte lesen und den Benutzer trotzdem einige Schieberegler optimieren lassen Wissen Sie, was sie sind und was erwartet wird.

Hat jemand das schon einmal getan (und getestet!) Vorbei und weiß, welches richtig ist?

War es hilfreich?

Lösung

Während ich die Fähigkeit untersuchte, die Bildschirmhelligkeit programmatisch zu ändern, bin ich auf diesen Artikel gestoßen Ändern der Bildschirmhelligkeit programmierend - mithilfe der Gama Ramp API.

Mit dem Debugger habe ich mir die Werte der von der bereitgestellten Werte angesehen GetDeviceGamaRamp() Funktion. Der Ausgang ist ein zweidimensionales Array, das als so etwas definiert ist WORD GammaArray[3][256]; und ist eine Tabelle mit 256 Werten, um die roten, grün- und blauen Werte von angezeigten Pixeln zu ändern. Die Werte, die ich gesehen habe, begannen mit einem Wert von Null (0) bei Index 0 und addierten einen Wert von 256, um den nächsten Wert zu berechnen. Die Sequenz ist also 0, 256, 512, ..., 65024, 65280 für Indizes 0, 1, 2, ..., 254, 255.

Mein Verständnis ist, dass diese Werte verwendet werden, um den RGB -Wert für jedes Pixel zu ändern. Durch Ändern des Tabellenwerts können Sie die Anzeigehelligkeit ändern. Die Wirksamkeit dieser Technik kann jedoch je nach Display -Hardware variieren.

Sie können diesen kurzen Artikel finden. Gamma -Kontrollen, von Interesse, wie es Gamma -Rampenspiegel jedoch aus Direct3D -Perspektive beschreibt. Der Artikel hat dies zu den Gamma -Rampenspiegeln zu sagen.

In Direct3D beschreibt der Begriff Gamma Ramp eine Reihe von Werten, die die Ebene einer bestimmten Farbkomponente - red, grün, blau - für alle Pixel im Rahmenpuffer auf neue Ebenen abbilden, die vom DAC für die Anzeige empfangen werden. Das Neuzufall wird mit drei Nachschlagtabellen durchgeführt, eine für jede Farbkomponente.

So funktioniert es: Direct3d nimmt ein Pixel aus dem Rahmenpuffer und bewertet seine individuellen rot-, grün- und blauen Farbkomponenten. Jede Komponente wird durch einen Wert von 0 bis 65535 dargestellt. Direct3d nimmt den ursprünglichen Wert auf und indexiert ihn, um ein 256-Element-Array (Rampe) zu indexieren, wobei jedes Element einen Wert enthält, der das ursprüngliche ersetzt. Direct3D führt diesen Nachblick und Ersatzprozess für jede Farbkomponente jedes Pixels im Rahmenpuffer durch, wodurch die endgültigen Farben für alle Pixel auf dem Bildschirm geändert werden.

Nach der Online -Dokumentation für GetDeviceGamaRamp() und SetDeviceGamaRamp() Diese Funktionen werden in der Windows -API unterstützt, beginnend mit Windows 2000 Professional.

Ich habe ihre Quelle verwendet, die auf das folgende Beispiel in eine Windows -Anwendung eingefügt wurde, um den Effekt mithilfe von Werten aus dem referenzierten Artikel zu testen. Meine Tests wurden mit Windows 7 und einem AMD Radeon HD 7450 -Grafikadapter durchgeführt.

Bei diesem Test waren meine beiden Displays, ich habe zwei Displays, betroffen.

//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);

Als zusätzlicher Hinweis habe ich eine geringfügige Änderung der obigen Quelle vorgenommen, sodass ich die ersten beiden Zuordnungen so kommentierte, anstatt jede der RGB -Werte gleichermaßen zu ändern GammaArray[2][ik] wurde modifiziert. Das Ergebnis war ein gelblicher Guss zum Display.

Ich habe auch versucht, die obige Quelle in eine Schleife zu setzen, um zu überprüfen, wie sich das Display verändert hat, und es war ein ziemlicher Unterschied zu wBrightness=0 zu 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 bietet einen Online-MSDN-Artikel, Verwendung von Gamma -Korrektur, das ist Teil der Direct3D -Dokumentation, die die Grundlagen von Gamma wie folgt beschreibt:

Am Ende der Grafikpipeline, in der das Bild den Computer verlässt, um seine Reise entlang des Monitor -Kabels zu machen, gibt es ein kleines Stück Hardware, das Pixelwerte im laufenden Flug verändern kann. Diese Hardware verwendet in der Regel eine Nachschlagetabelle, um die Pixel zu transformieren. Diese Hardware verwendet die roten, grünen und blauen Werte, die von der Oberfläche angezeigt werden, um die Gamma-korrigierten Werte in der Tabelle nachzuschlagen, und sendet dann die korrigierten Werte anstelle der tatsächlichen Oberflächenwerte an den Monitor. Diese Lookup -Tabelle ist also eine Gelegenheit, jede Farbe durch andere Farbe zu ersetzen. Während die Tabelle diesen Leistungsniveau aufweist, besteht die typische Verwendung darin, Bilder subtil zu optimieren, um Unterschiede in der Reaktion des Monitors zu kompensieren. Die Reaktion des Monitors ist die Funktion, die den numerischen Wert der roten, grünen und blauen Komponenten eines Pixels mit der angezeigten Helligkeit dieses Pixels bezieht.

Zusätzlich die Die Softwareanwendung Redshift hat eine Seite Windows Gamma -Einstellungen Das hat dies über Microsoft Windows zu sagen.

Beim Portieren von Rotverschiebung auf Windows stieß ich in Schwierigkeiten, als ich eine Farbtemperatur von weniger als 4500 km einstellte. Das Problem ist, dass Windows Einschränkungen dafür festlegt, welche Arten von Gamma -Anpassungen vorgenommen werden können, wahrscheinlich als Mittel, um den Benutzer vor bösen Programmen zu schützen, die die Farben invertieren, das Display leer sind oder einen anderen nervigen Trick mit den Gamma -Rampen spielen. Diese Art der Einschränkung ist vielleicht verständlich, aber das Problem ist der vollständige Mangel an Dokumentation dieser Funktion (SetDeviceGammaramp auf msdn). Ein Programm, das versucht, eine Gamma -Rampe festzulegen, die nicht zulässig ist, wird einfach mit einem generischen Fehler fehlschlagen, wobei der Programmierer sich fragt, was schief gelaufen ist.

Andere Tipps

Ich habe das nicht getestet, aber wenn ich raten musste, waren frühe Grafikkarten bei der Implementierung von SetDeviceGammaramp () nicht standardmäßig, als das Doom geschrieben wurde und manchmal den Lobyte verwendete und manchmal die Hibyte des Wortwerts verwendete. Der Konsens bewegte sich nur um die Hibyte, daher die word_value = byte_value<<8.

Hier ist ein weiterer Datenpunkt aus der Psychopopy -Bibliothek (in Python), der nur Loch- und Hibyte -Tausch ist:

 """Sets the hardware look-up table, using platform-specific ctypes functions. 
 For use with pyglet windows only (pygame has its own routines for this). 
 Ramp should be provided as 3x256 or 3x1024 array in range 0:1.0 
 """ 
if sys.platform=='win32':   
    newRamp= (255*newRamp).astype(numpy.uint16) 
    newRamp.byteswap(True)#necessary, according to pyglet post from Martin Spacek 
    success = windll.gdi32.SetDeviceGammaRamp(pygletWindow._dc, newRamp.ctypes) 
    if not success: raise AssertionError, 'SetDeviceGammaRamp failed' 

Es scheint auch, dass Windows nicht allen Gamma -Einstellungen zulässt, siehe:http://jonls.dk/2010/09/windows-gamma-adjustments/

Aktualisieren:

Die ersten Windows -APIs für die Gamma -Steuerung sind die SetDeviceGammaramp von Windows Graphics Device Interface (GDI) und getDeviceGammaramp. Diese APIs funktionieren mit drei 256-Eingangs-Wörternarrays, wobei jedes Wort Null bis eins kodiert, dargestellt durch die Wortwerte 0 und 65535. Die zusätzliche Genauigkeit eines Wortes ist in der Regel nicht in tatsächlichen Hardware-Nachschlagtabellen verfügbar, aber diese APIs waren jedoch gedacht, flexibel zu sein. Diese APIs ermöglichen im Gegensatz zu den anderen, die später in diesem Abschnitt beschrieben wurden, nur eine kleine Abweichung von einer Identitätsfunktion. Tatsächlich muss jeder Eintrag in der Rampe innerhalb von 32768 des Identitätswerts liegen. Diese Einschränkung bedeutet, dass keine App das Display vollständig schwarz oder auf eine andere unlesbare Farbe verwandeln kann.

http://msdn.microsoft.com/en-us/library/windows/desktop/jj635732(v=vs.85).aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top