Domanda

Vorrei aggiungere la possibilità di regolare lo schermo gamma all'avvio dell'applicazione e ripristinarlo all'uscita. Mentre è discutibile se si dovrebbe comettini di gamma (personale lo trovo inutile e dannoso), ma ehi, alcune persone si aspettano di poter fare quel tipo di cose.

È anche una semplice chiamata API, quindi è tutto facile, giusto?

MSDN dice: "La rampa gamma è specificata in tre array di 256 elementi di parole ciascuno [...] i valori devono essere conservati nei bit più significativi di ogni parola per aumentare l'indipendenza del DAC.". Questo significa, nella mia comprensione, qualcosa di simile word_value = byte_value<<8, il che sembra piuttosto strano, ma è così che l'ho letto.

Il codice sorgente Doom3 contiene una funzione che prende tre matrici di char valori e li converte in una matrice di uint16_t valori che hanno lo stesso valore di byte Entrambi nella metà superiore e inferiore. In altre parole qualcosa di simile word_value = (byte_value<<8)|byte_value. Questo è altrettanto strano, ma quello che è peggio è non è lo stesso di sopra.

Esistono anche alcuni frammenti di codice su Internet su vari siti di programmatore di hobby (apparentemente uno rubato dall'altro, perché sono identici alla lettera) che fanno qualche oscuro matema E serraggio a 65535. Non sono sicuro di cosa si tratta, ma mi sembra una totale assurdità, e di nuovo non è lo stesso di uno dei due precedenti.

Cosa dà? Deve essere ben definito-senza indovinare-come devono essere forniti i dati che fornite? Alla fine, quello che si farà è leggere i valori originali e consentire comunque all'utente modificare alcuni cursori (e facoltativamente salvare quel blob su disco con la configurazione dell'utente), ma comunque ... per modificare questi valori, è necessario farlo Sapere cosa sono e cosa ci si aspetta.

Qualcuno ha già fatto (e testato!) Questo e sa quale è giusto?

È stato utile?

Soluzione

Mentre studiavo la capacità di cambiare programmaticamente la luminosità dello schermo, mi sono imbattuto in questo articolo Modifica in programma la luminosità dello schermo - utilizzando l'API Gama Ramp.

Usando il debugger, ho dato un'occhiata ai valori forniti dal GetDeviceGamaRamp() funzione. L'uscita è un array bidimensionale definito come qualcosa di simile WORD GammaArray[3][256]; ed è una tabella di 256 valori per modificare i valori rossi, verdi e blu dei pixel visualizzati. I valori che ho visto sono iniziati con un valore di zero (0) all'indice 0 e aggiungendo un valore di 256 per calcolare il valore successivo. Quindi la sequenza è 0, 256, 512, ..., 65024, 65280 per gli indici 0, 1, 2, ..., 254, 255.

La mia comprensione è che questi valori vengono utilizzati per modificare il valore RGB per ciascun pixel. Modificando il valore della tabella è possibile modificare la luminosità del display. Tuttavia, l'efficacia di questa tecnica può variare a seconda dell'hardware del display.

Potresti trovare questo breve articolo, Controlli gamma, di interesse in quanto descrive i livelli di rampa di gamma sebbene da una prospettiva Direct3D. L'articolo ha questo da dire sui livelli di rampa gamma.

In Direct3d, il termine gamma ramp descrive una serie di valori che mappano il livello di un particolare componente di colore - rosso, verde, blu - per tutti i pixel nel tampone del telaio a nuovi livelli ricevuti dal DAC per la visualizzazione. La rimappatura viene eseguita tramite tre tabelle di ricerca, una per ogni componente a colori.

Ecco come funziona: Direct3d prende un pixel dal tampone della cornice e valuta i suoi singoli componenti di colore rosso, verde e blu. Ogni componente è rappresentato da un valore da 0 a 65535. Direct3d prende il valore originale e lo utilizza per indicizzare un array di elementi da 256 (la rampa), in cui ogni elemento contiene un valore che sostituisce quello originale. Direct3d esegue questo processo di ricerca e sostituzione per ciascun componente a colori di ciascun pixel nel buffer della cornice, cambiando così i colori finali per tutti i pixel sullo schermo.

Secondo la documentazione online per GetDeviceGamaRamp() e SetDeviceGamaRamp() Queste funzioni sono supportate nell'API di Windows a partire da Windows 2000 Professional.

Ho usato la loro fonte condensata all'esempio seguente inserito in un'applicazione Windows per testare l'effetto utilizzando i valori dall'articolo di riferimento. Il mio test è stato eseguito con Windows 7 e un adattatore grafico AMD Radeon HD 7450.

Con questo test entrambi i miei display, ho due display, sono stati interessati.

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

Come nota aggiuntiva, ho apportato una leggera modifica alla sorgente sopra in modo che invece di modificare ciascuno dei valori RGB allo stesso modo, ho commentato i primi due incarichi in modo che solo che siano GammaArray[2][ik] è stato modificato. Il risultato è stato un cast giallastro sul display.

Ho anche provato a mettere la fonte sopra in un ciclo per verificare come il display è cambiato ed è stata una vera differenza wBrightness=0 a 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 fornisce un articolo MSDN online, Usando la correzione gamma, che fa parte della documentazione direct3d che descrive le basi della gamma come segue:

Alla fine della pipeline grafica, proprio dove l'immagine lascia il computer per fare il suo viaggio lungo il cavo del monitor, c'è un piccolo pezzo di hardware che può trasformare i valori dei pixel al volo. Questo hardware in genere utilizza una tabella di ricerca per trasformare i pixel. Questo hardware utilizza i valori rossi, verdi e blu che provengono dalla superficie per essere visualizzati per cercare valori corretti da gamma nella tabella e quindi invia i valori corretti al monitor anziché ai valori di superficie effettivi. Quindi, questa tabella di ricerca è un'opportunità per sostituire qualsiasi colore con qualsiasi altro colore. Mentre la tabella ha quel livello di potenza, l'uso tipico è quello di modificare le immagini per compensare le differenze nella risposta del monitor. La risposta del monitor è la funzione che mette in relazione il valore numerico dei componenti rossi, verdi e blu di un pixel con quella luminosità mostrata da pixel.

Inoltre il Applicazione software Redshift ha una pagina Regolazioni gamma di Windows Il che ha questo da dire su Microsoft Windows.

Quando si porta a spostamento verso le finestre, mi sono imbattuto nei guai quando si imposta una temperatura di colore inferiore a circa 4500k. Il problema è che Windows imposta limitazioni su quali tipi di regolazioni gamma possono essere apportate, probabilmente come mezzo per proteggere l'utente dai programmi malvagi che invertono i colori, in bianco e giocano un altro trucco fastidioso con le rampe gamma. Questo tipo di limitazione è forse comprensibile, ma il problema è la completa mancanza di documentazione di questa funzione (Setdevicegammaramp su msdn). Un programma che cerca di impostare una rampa gamma che non è consentita fallirà semplicemente con un errore generico lasciando il programmatore chiedendosi cosa è andato storto.

Altri suggerimenti

Non l'ho testato, ma se dovessi indovinare, le prime schede grafiche non erano standard nella loro implementazione di SetDeviceGammaramp () quando Doom veniva scritto e talvolta usava il lobyte e talvolta usava l'Hibyte del valore della parola. Il consenso è passato all'uso solo dell'Hibyte, da cui il word_value = byte_value<<8.

Ecco un altro punto dati, dalla biblioteca psicopia (in Python) che sta scambiando lobyte e hibyte:

 """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' 

Sembra anche che Windows non consenta tutte le impostazioni gamma, vedi:http://jonls.dk/2010/09/windows-gamma-adjustments/

Aggiornare:

Le prime API di Windows che offrono il controllo gamma sono SetDeviceGammaramp di Windows Graphics Device Interface (GDI) e GetDeviceGammaramp. Queste API funzionano con tre array di parole da 256-entry, con ogni parola che codifica zero fino a una, rappresentata dai valori delle parole 0 e 65535. L'ulteriore precisione di una parola in genere non è disponibile nelle tabelle di ricerca hardware effettive, ma queste API erano destinato ad essere flessibile. Queste API, in contrasto con le altre descritte più avanti in questa sezione, consentono solo una piccola deviazione da una funzione di identità. In effetti, qualsiasi voce nella rampa deve essere entro 32768 dal valore di identità. Questa restrizione significa che nessuna app può trasformare il display completamente nero o in qualche altro colore illeggibile.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top