windowspythonbrightnessapigamma

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.


Solution

  • 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.