Charitra Agarwal
Charitra Agarwal

Reputation: 492

Control brightness in Windows at software Level

It might be possible for a similar question to be already present on the site, but I have searched a lot and didn't find any relevant solution, so I'm posting it here.

I'm making a Night Light Application, which has two options-

  1. Lessen the Brightness of the PC

  2. Apply a Blue light filter mask over the screen.

I'm making this app cross platform, so I've already found a solution for Linux Systems, where I've been making use of xrandr utility to adjust the brightness and gamma at the software level, and my app works flawlessly.

The main problem is for Windows systems, where the brightness feature is only available for portable screens such as for a Laptop. I cannot find any solution for this. I made use of Qt5 for making a translucent app window which works good, but doesn't meet the requirement because the things displayed at kernel level are not masked like the cursor, taskbar, start menu, action center, and lots of other.

I searched a lot and lot, which included Microsoft Developer Network, where documentation included the Win32 API where brightness feature was present, but it didn't work for me, as I had a Desktop PC.

So my main problem is, How can I ajust the brightness of all Windows PC, including Laptops, Desktops n all others.

I'm working on Python with ctypes module. I'm not that much familiar with VC+ and I cannot even afford to install it on my system as it is too much storage and resource intensive.

I primarily want to modify the output going to the physical monitor, that is to modify the Gamma values to get appropriate brightness and Yellow tincture.

I got something called gdi32.dll which deals with the outputs to screens, but I cannot find a way out as everything on the Internet is alongside C++.

Also, I cannot even provide my try code, as I'm not that much familiar to C type coding in Python.

Also, the thing I want to do, Intel Graphics Command Center already does it on my desktop. If it can do it on at a software level, then I know its possible programmatically.

Can anyone tell is this possible what I'm thinking, and if yes, how can I achieve this?
I don't want the source code, I just want the way out for that.

Maybe GammaRamp from the Gdi32 API can be used, but I don't know how to begin.

This is a thread which actually asked this, but I didn't get my answer from here, and newbies are restricted from commenting, so I didn't have any choice than to post this question here.

Upvotes: 2

Views: 1705

Answers (2)

Charitra Agarwal
Charitra Agarwal

Reputation: 492

I have found the way for the problem.

We can use GetDeviceGammaRamp and SetDeviceGammaRamp from the gdi32.dll library in Windows OS to set the brightness level.

To call these functions through Python, we can use ctypes module. Below is the sample code that can set brightness of in Windows 10 via Python.

import ctypes


def displayGammaValues(lpRamp):
    """
    Displays the GammaArray of 256 values of R,G,B individually
    :param lpRamp: GammaArray
    :return: None
    """
    print("R values: ", end=' ')
    for j in range(256):
        print(lpRamp[0][j], end=' ')
    print()

    print("G values: ", end=' ')
    for j in range(256):
        print(lpRamp[0][j], end=' ')
    print()

    print("B values: ", end=' ')
    for j in range(256):
        print(lpRamp[0][j], end=' ')
    print(), print()


def changeGammaValues(lpRamp, brightness):
    """
    Modifies the Gamma Values array according to specified 'Brightness' value
    To reset the gamma values to default, call this method with 'Brightness' as 128
    :param lpRamp: GammaArray
    :param brightness: Value of brightness between 0-255
    :return: Modified GammaValue Array
    """
    for i in range(256):
        iValue = i * (brightness + 128)
        if iValue > 65535: iValue = 65535
        lpRamp[0][i] = lpRamp[1][i] = lpRamp[2][i] = iValue
    return lpRamp


if __name__ == '__main__':
    brightness = 100    # can be aby value in 0-255 (as per my system)
    GetDC = ctypes.windll.user32.GetDC
    ReleaseDC = ctypes.windll.user32.ReleaseDC
    SetDeviceGammaRamp = ctypes.windll.gdi32.SetDeviceGammaRamp
    GetDeviceGammaRamp = ctypes.windll.gdi32.GetDeviceGammaRamp

    hdc = ctypes.wintypes.HDC(GetDC(None))
    if hdc:
        GammaArray = ((ctypes.wintypes.WORD * 256) * 3)()
        if GetDeviceGammaRamp(hdc, ctypes.byref(GammaArray)):
            print("Current Gamma Ramp Values are:")
            displayGammaValues(GammaArray)

            GammaArray = changeGammaValues(GammaArray, brightness)

            print("New Current Gamma Ramp Values are:")
            displayGammaValues(GammaArray)

            if SetDeviceGammaRamp(hdc, ctypes.byref(GammaArray)): print("Values set successfully!")
            else: print("Unable to set GammaRamp")
        if ReleaseDC(hdc): print("HDC released")
    else: print("HDC not found")

This sets the brightness value, that's between 0-255. Values may differ system-to-system, so preferable range for brightness is 0 - 128 where 128 is the default brightness.

Upvotes: 2

Todd Rylaarsdam
Todd Rylaarsdam

Reputation: 478

FYI windows already has a monitor blue shade/color shift built in. Dimming external monitor outputs on a desktop is likely not possible.

You'll need to hook into the windows API somehow to control windows functions. There's some documentation about adjusting color temperature (making that warmer would essentially add a "blue light" filter to a screen on microsoft's website.

https://learn.microsoft.com/en-us/windows/win32/api/highlevelmonitorconfigurationapi/nf-highlevelmonitorconfigurationapi-setmonitorcolortemperature.

In terms of executing a small CPP script that actually can interface with windows, you can write a small CPP program, then compile it and execute from python using (slightly modified from this question)

import os
import subprocess

for filename in os.listdir(os.getcwd()):   
    proc = subprocess.Popen(["./prog", filename])
    proc.wait()

However if you don't have the room to install visual studio compile tools, you won't be able to compile a small CPP script locally. There are a few online services that would be able to do that for you though.

Upvotes: 0

Related Questions