Исследуя возможность программного изменения яркости экрана, я наткнулся на эту статью Программирование изменения яркости экрана - с помощью Gama Ramp API .
Используя отладчик, я взглянул на значения, предоставляемые функцией GetDeviceGamaRamp()
. Выходными данными является двумерный массив, определенный как что-то вроде WORD GammaArray[3][256];
, и таблица из 256 значений для изменения значений красного, зеленого и синего отображаемых пикселей. Значения, которые я увидел, начинаются со значения ноль (0) с индекса 0 и добавления значения 256 для вычисления следующего значения. Таким образом, последовательность составляет 0, 256, 512, ..., 65024, 65280 для индексов 0, 1, 2, ..., 254, 255.
Насколько я понимаю, эти значения используются для изменения значения RGB для каждого пикселя. Изменяя значение таблицы, вы можете изменить яркость дисплея. Однако эффективность этого метода может варьироваться в зависимости от аппаратного обеспечения дисплея.
Вы можете найти эту краткую статью, Gamma Controls , интересной, поскольку она описывает уровни гамма-изменения с точки зрения Direct3D. В статье говорится об уровнях гамма-всплеска.
В Direct3D термин гамма-наклон описывает набор значений, которые отображаются
уровень определенного компонента цвета - красный, зеленый, синий - для всех
пикселей в буфере кадра на новые уровни, которые получает ЦАП
для отображения. Перераспределение выполняется в виде трех просмотров
таблицы, по одной на каждый компонент цвета.
Вот как это работает: Direct3D берет пиксель из буфера кадра и
оценивает отдельные компоненты красного, зеленого и синего цвета. каждый
Компонент представлен значением от 0 до 65535. Direct3D занимает
исходное значение и использует его для индексации массива из 256 элементов (
рампа), где каждый элемент содержит значение, которое заменяет исходный
один. Direct3D выполняет этот поиск и заменяет процесс для каждого цвета
компонент каждого пикселя в буфере кадра, тем самым изменяя
окончательные цвета для всех пикселей на экране.
В соответствии с онлайн-документацией для GetDeviceGamaRamp()
и SetDeviceGamaRamp()
эти функции поддерживаются в API Windows, начиная с Windows 2000 Professional.
Я использовал их источник, сжатый до следующего примера, вставленного в приложение Windows, чтобы проверить эффект, используя значения из указанной статьи. Мое тестирование было проведено с Windows 7 и графическим адаптером AMD Radeon HD 7450.
При этом тесте оба моих дисплея, у меня есть два дисплея, были затронуты.
//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 я закомментировал первые два назначения, чтобы было изменено только 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 имеется страница настроек гаммы Windows , в которой говорится это о Microsoft Windows.
При портировании Redshift на Windows у меня возникли проблемы при установке цветовой температуры ниже примерно 4500K.Проблема заключается в том, что Windows устанавливает ограничения на то, какие виды гамма-коррекции могут быть сделаны, вероятно, как средство защиты пользователя от злых программ, которые инвертируют цвета, очищают экран или играют какую-то другую надоедливую хитрость с гамма-рампами.Ограничения такого рода, возможно, понятны, но проблема заключается в полном отсутствии документации этой функции ( SetDeviceGammaRamp на MSDN ).Программа, которая пытается установить недопустимую гамма-диаграмму, просто потерпит неудачу с общей ошибкой, оставляя программиста в недоумении, что пошло не так.