Announcement

Collapse
No announcement yet.

Brightness

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Brightness

    I had someone ask me to reduce the brightness of an app I wrote.

    So I wrote a function that darkens the app by removing the same amount repeatedly from the R, G, and B components of the colors. Code below.

    But, I'm not sure that what I did would be correctly called "brightness".

    I ran across an API called SetDeviceGammaRamp, examples of which are hard to come by.

    I also can see that my monitor menu allows me to manually adjust "brightness".

    And I read about, but cannot find (Win10), a Setting that can adjust brightness.

    Would someone who understands color better than I weigh in on the topic?


    Code:
    Sub DarkenColor(iColor As Long)
       Local R,G,B,DarkenAmount As Long
    
       DarkenAmount = -25
    
          'get RGB components    
       R = iColor Mod 256      
       G = (iColor\256) Mod 256
       B = (iColor\256\256) Mod 256
    
          'darken
       R = Max(0,R+DarkenAmount)
       G = Max(0,G+DarkenAmount)
       B = Max(0,B+DarkenAmount)
    
       If R<20 And G<20 And B<20 Then
          ResetColors    'once mostly black, restore original colors (kept elsewhere)
       Else
          iColor = RGB(R,G,B)
       End If
    End Sub

  • #2
    Harkening back to some of our previous discussions about color... You are working in the RGB colorspace, and you want to perform a change in the HSW (Hue, Saturation, Whiteness) colorspace. So you should convert from RGB to HSW, reduce the W component by a fixed amount, convert back to RGB, and paint (whatever) using the resulting color. That will produce a color with (optimally) the same hue and saturation, but a lower brightness.

    Also consider reducing S by a fixed amount at the same time, to avoid darkened images with overly-saturated colors.
    "Not my circus, not my monkeys."

    Comment


    • #3
      Hi Eric!
      Thanks for the response!

      Yes, I recall some discussion on the topic, and have also been reading some comments on it today.

      I've assumed that reducing brightness is simply transitioning a color to black, which is what the RGB approach does.

      Do I understand correctly that you're saying that the HSW approach gives a better transition to black and can you speak to what better means in this case? If I gradually decrease brightness using each approach side by side, what would make the HSW approach more visually desirable than the RGB approach?

      ... added ... I can feel a test app coming on!

      Comment


      • #4
        Oh! Also, Eric, is it the case that there's no API which would redirect the monitor to reduce brightness of everything it displays? Is the only approach available to modify the colors via code?

        The SetDeviceGammaRamp API seems to be promising but I've found little discussion on the web about it.

        Comment


        • #5
          Let's say you start out with a rectangle that is orange.

          %RGB_ORANGE = 00A5FF

          That's B=0, G=165, R=255

          If you reduce all three by (say) 150, you'd get

          B=0, G=15, R=105

          The ratio of green to red is now very different, so the hue of that rectangle will no longer appear "orange" to the eye, it will be almost pure red. Different colors will be "skewed" in different directions, resulting in generally odd-looking colors.

          I'm not aware of any API calls that directly affect the monitor brightness, but then again I wasn't aware of SetDeviceGammaRamp. FYI "gamma" does not (by definition) affect either the blacks or whites in an image, it affects the linearity of the transition from black to white. Hard to explain without a diagram, but it will not control actual brightness and contrast. And apparently it only works with some video drivers.
          "Not my circus, not my monkeys."

          Comment


          • #6
            Hi Eric!
            Thanks for the additional response. I think I'll go make a simple test and watch the colors. Using the RGB approach, I've not seen anything that looks totally out of whack, but then I've not seen the HSW approach to know what I'm missing!

            Comment


            • #7
              you can see the effects of different Color Space RGB, HSV, HSL etc. at this site http://colorizer.org/

              I have not seen HSW but from Eric's description looks like HSV.

              The following API for Monitor brightness (min requirement Vista) may help in your endeavor, SetMonitorBrightness part of the Monitor Configuration Functions

              Found in Jose Roca's includes highlevelmonitorconfigurationapi.inc

              Comment


              • #8
                Originally posted by Gary Beene View Post
                I had someone ask me to reduce the brightness of an app I wrote.

                So I wrote a function that darkens the app by removing the same amount repeatedly from the R, G, and B components of the colors. Code below.

                But, I'm not sure that what I did would be correctly called "brightness".
                It is the same as gray scale, which converts colors to shades of gray.
                This uses the relative brightness of each color to get a monochrome output.
                Reducing in those same proportions should result in the outcomes desired.
                In my quick tests, this seems to work quite well.
                Code:
                TYPE bgra
                    b AS BYTE
                    g AS BYTE
                    r AS BYTE
                    a AS BYTE
                END TYPE
                
                SUB dimgraphic(win AS DWORD, ctl AS LONG)
                    'pass dialog and control id
                    LOCAL strbuf AS STRING, pxl_arr() AS bgra, x, y, p AS LONG
                    ' get buffer size to x, y
                    CONTROL GET CLIENT win, ctl TO x, y
                    ' calculate buffer array length
                    x = (x * y) -1
                    GRAPHIC ATTACH win, ctl
                    ' get string from GRAPHIC object
                    GRAPHIC GET BITS TO strbuf
                    ' create array a buffer, offset eight bytes for two long values for x, y
                    REDIM pxl_arr(x) AT STRPTR(strbuf) + 8
                    FOR y = 0 TO x
                        ' use gray scale brightness values to dim
                        pxl_arr(y).r -= pxl_arr(y).r * .0701
                        pxl_arr(y).g -= pxl_arr(y).g * .0423
                        pxl_arr(y).b -= pxl_arr(y).b * .0886
                    NEXT
                    ' set GRAPHIC object from string
                    GRAPHIC SET BITS strbuf
                END SUB
                The world is strange and wonderful.*
                I reserve the right to be horrifically wrong.
                Please maintain a safe following distance.
                *wonderful sold separately.

                Comment


                • #9
                  Not to distract but I liked this article on grayscale.
                  http://www.tannerhelland.com/3643/gr...algorithm-vb6/
                  I am working on an idea of using the grayscale values to help find the best near color differences when other calculations are the same. But I have not put my thoughts to code yet.
                  While I have posted.
                  Gary, we have set many desktop background colors to either a charcoal color like you might see with photoshop on YouTube or a brownish maroon color and we only use solid colors and remove aero and all fancy screen themes. Matter of fact we disable themes. If your using text with a bkackground and find a nice background that is easy on the eyes. A white background is hard in my eyes
                  p purvis

                  Comment


                  • #10
                    Kurt, excellent suggestion using those ratios... It should provide pretty good results without the complexities of the HSW method I suggested.

                    I think the key to Gary's original question is proper multiplication -- not the subtraction of a fixed amount -- from each color.
                    "Not my circus, not my monkeys."

                    Comment


                    • #11
                      Originally posted by Eric Pearson View Post
                      Kurt, excellent suggestion using those ratios... It should provide pretty good results without the complexities of the HSW method I suggested.

                      I think the key to Gary's original question is proper multiplication -- not the subtraction of a fixed amount -- from each color.
                      It is the same process.
                      I only subtracted because I didn't want to take the time to do the math on multiplication.
                      I used the values I already had. One could multiply the amount subtracted, of course.
                      More simple still, one might take the total brightness, and each color as a percentage
                      of the whole, then reduce the total brightness and give each color the proper value as
                      an equivalent percentage of the new total value. But it requires more math inline and
                      will slow the process. The advantage is not needing magic numbers for brightness.
                      Code:
                      SUB dimgraphic2(win AS DWORD, ctl AS LONG, percent AS LONG)
                          'pass dialog and control id
                          LOCAL strbuf AS STRING, pxl_arr() AS bgra, x, y, p, nv AS LONG
                          ' get buffer size to x, y
                          CONTROL GET CLIENT win, ctl TO x, y
                          ' calculate buffer array length
                          x = (x * y) -1
                          GRAPHIC ATTACH win, ctl
                          ' get string from GRAPHIC object
                          GRAPHIC GET BITS TO strbuf
                          ' create array a buffer, offset eight bytes for two long values for x, y
                          REDIM pxl_arr(x) AT STRPTR(strbuf) + 8
                          FOR y = 0 TO x
                              'reduce each color to a lower equivalent percentage of the total
                              p = ((pxl_arr(y).r + pxl_arr(y).g + pxl_arr(y).b) * percent) \ 100
                              nv = (p * percent) \ 100
                              pxl_arr(y).r = (nv * pxl_arr(y).r) / p
                              pxl_arr(y).g = (nv * pxl_arr(y).g) / p
                              pxl_arr(y).b = (nv * pxl_arr(y).b) / p
                          NEXT
                          ' set GRAPHIC object from string
                          GRAPHIC SET BITS strbuf
                      END SUB
                      The world is strange and wonderful.*
                      I reserve the right to be horrifically wrong.
                      Please maintain a safe following distance.
                      *wonderful sold separately.

                      Comment


                      • #12
                        Kurt, That routine is an awesome great example of efficient tight code of working with all pixels inside a bitmap. Whether you posted similar code like that before or not. It taught me a lot. That should be a poster girl example for how to use GET and SET Bits. Thank you
                        p purvis

                        Comment

                        Working...
                        X