Announcement

Collapse
No announcement yet.

Splitting long-integer RGB values into R, G, and B

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

  • Splitting long-integer RGB values into R, G, and B

    Graphics aren't my thing, I'm afraid. Actually, nothing is really "my thing," when it comes to programming.

    I dug around a bit, and found that the PBCC4.04 function RGB() does not have a true inverse function; there is a BGR() function, but that does something different.

    Those of you who do graphics programs probably know about RGB():

    long RGB(r, g, b)
    where r, g, and b are (integer?) color values from 0 to 255.

    What I need is a function that takes a long integer (that is an RGB color value) and splits it back into its constituent r, g, and b values, which I can then manipulate and do whatever with.

    Is there actually a formula for this out there already, or is this going to involve some code breaking? I printed out the value of the RGB() function six times with various values for the r, g, and b values to see if there was an obvious pattern, but there isn't as far as I can see:

    RGB(0,0,0)=0 (this doesn't defy logic)
    RGB(1,1,1)=65793 (OK, a bit unexpected)
    RGB(10,10,10)=657930 (very unexpected)
    RGB(12,34,56)=3678732 (not very enlightening)
    RGB(10,20,30)=1971210 (ditto)
    RGB(13,25,46)=3021069 (still in the dark)

    So there we have it. I'm hoping that someone else has run into this before; otherwise I may have to write a program to crack the pattern (if there is one), which is going to be painful.

    Any thoughts?

  • #2
    Run this, enter either a decimal number or a hexidecimal preceeded by &h
    Code:
    Function PBMain
     Local c$
     Local col As Long
     Local Bcol As Long
     Local Gcol As Long
     Local Rcol As Long
     Do
      Cls
      Input "Type color code:  ", c$
      If c$ = "" Then Exit Function
      col = Val(c$)
      Print " ";c$
      Print col
      Print " &h";Hex$(col)
      '-------------------------------------------
      Bcol = col And &h0000FF
      Gcol = col And &h00FF00 :Shift Right Gcol,8
      Rcol = col And &hFF0000 :Shift Right Rcol,16
      '-------------------------------------------
      Print Rcol, Gcol, Bcol
      Print " ";Hex$(Rcol),Hex$(Gcol),Hex$(Bcol)
      WaitKey$
     Loop
    End Function
    Last edited by Mark Hunter; 22 Dec 2007, 12:23 AM.
    Politically incorrect signatures about immigration patriots are forbidden. Searching “immigration patriots” is forbidden. Thinking about searching ... well, don’t even think about it.

    Comment


    • #3
      Mark,

      Red is in byte 0, Green in byte 1, and Blue in byte 2.
      Code:
      'this:
      '-------------------------------------------
        Bcol = col And &h0000FF
        Gcol = col And &h00FF00 :Shift Right Gcol,8
        Rcol = col And &hFF0000 :Shift Right Rcol,16
      '-------------------------------------------
      'should be:
      '-------------------------------------------
        [B]R[/B]col = col And &h0000FF
        Gcol = col And &h00FF00 :Shift Right Gcol,8
        [B]B[/B]col = col And &hFF0000 :Shift Right [B]B[/B]col,16
      '-------------------------------------------
      Jonathan,

      To work with the red, green and blue by name
      Code:
      type RGBType
        R as byte
        G as byte
        B as byte
        nu as byte
      end type
      union RGBUnion
        byts as RGBType
        lg as long
      end union
      
      'in code:
      local col as RGBUnion
      'set red to 128
      col.byts.R = 128
      'set a console's foreground to col and background to white
      color col.lg, &hFFFFFF
      Cheers,
      Last edited by Dale Yarker; 22 Dec 2007, 03:22 AM. Reason: add TYPE and UNION example
      Dale

      Comment


      • #4
        Another example
        Code:
        #INCLUDE "WIN32API.INC"
         
        Sub IntegerToRGB (ByVal IntegerValue As Long, lRed As Long, lGreen As Long, lBlue As Long)
         
          lRed = Val("&h" + Mid$(Hex$(IntegerValue,6),5,2))
          lGreen = Val("&h" + Mid$(Hex$(IntegerValue,6),3,2))
          lBlue = Val("&h" + Mid$(Hex$(IntegerValue,6),1,2))
         
        End Sub 
        '------------------/IntegerToRGB
         
        Function PbMain()
         Local IntegerValue, r, b, g As Long 
         Local lRed, lGreen, lBlue As Long 
         Local sMsg, sTitle As String 
         
          r = 13 : g = 25 : b = 46              ' <-test values
          IntegerValue = RGB(r,g,b)
         
          IntegerToRGB (IntegerValue, lRed, lGreen, lBlue) 
         
          sMsg = "Red"+$Tab+  str$(lRed)+$CR+ _
                 "Green"+$Tab+str$(lGreen)+$CR+ _
                 "Blue"+$Tab+ str$(lBlue)
          sTitle = str$(RGB(r,g,b))
          MessageBox 0, ""+sMsg, "Int Value"+sTitle ,%MB_ICONINFORMATION OR %MB_OK
         
        End Function
        '------------------/PBMain
        Rgds, Dave

        Comment


        • #5
          Whoops, Jonathan asked for "...splits it back into its constituent ..." and I only showed a different way to set it.

          Add to above:
          Code:
          local Rcol as long
          local Bcol as long
          local Gcol as long
          '
          Rcol = col.byts.R
          Gcol = col.byts.G
          Bcol = col.byts.B
          You can also get to separate colors within a long color value by a byte pointer.
          local pColor as byte pointer
          pColor = varptr(col)
          Rcol = @pColor 'at pointer + 0
          incr pColor
          Gcol = @pColor 'at pointer + 1
          incr pColor
          Bcol = @pColor 'at pointer + 2

          Lots of ways to "skin the cat" in programming.

          What seems like wierd numbers (like "RGB(10,10,10)=657930 (very unexpected)") is a consequence of viewing as decimal. In this case:
          657930 = 10 + (10 * 256) + (10 * 65536)

          C U L -
          Dale

          Comment


          • #6
            Some other possibilities: http://www.powerbasic.com/support/pb...ad.php?t=13159
            Adam Drake
            PowerBASIC

            Comment


            • #7
              When going the UNION way,
              If one want to simplify it a little further
              then using a type without a variable name give a little plus.
              PowerBASIC describe it as "Structure within structure"

              Code:
               
              #COMPILE EXE '#Win 8.04#
              #DIM ALL
              #INCLUDE "WIN32API.INC" '#2005-01-27#
               
              TYPE ColorBytes
                R AS BYTE 'Red
                G AS BYTE 'Green
                B AS BYTE 'Blue
                A AS BYTE 'Alpha
              END TYPE
               
              UNION ColorUnion
                RGB AS DWORD
                ColorBytes '<- Look ma, no var, just the TYPE
              END UNION    '   so MyColor.R could be used instead of MyColor.SomeVar.R
               
              '______________________________________________________________________________
               
              FUNCTION PBMAIN() AS LONG
               LOCAL MyColor AS ColorUnion
               
               MyColor.RGB = RGB(1, 2, 0)
               MyColor.B   = 3
               
               MessageBox %HWND_DESKTOP, "RGB" & $TAB & HEX$(MyColor.RGB, 8) & $CRLF & _
                                         "R"   & $TAB & HEX$(MyColor.R)      & $CRLF & _
                                         "G"   & $TAB & HEX$(MyColor.G)      & $CRLF & _
                                         "B"   & $TAB & HEX$(MyColor.B), _
                                         "RGB and R, G, B", %MB_ICONINFORMATION OR %MB_OK
               
              END FUNCTION
              '______________________________________________________________________________
              Last edited by Pierre Bellisle; 22 Dec 2007, 12:51 PM.

              Comment


              • #8
                Code:
                FUNCTION PbMain() AS LONG
                
                  CALL TestRgbMacros()
                
                END FUNCTION
                
                
                MACRO mGetRed   (Rgbvalue)  = Rgbvalue AND &h0FF
                MACRO mGetGreen (rgbvalue)  = (Rgbvalue AND &h0FF00)   \ &h100
                MACRO mGetBlue  (rgbvalue)  = (rgbvalue AND &h0FF0000) \ &h10000
                
                
                FUNCTION TestRGBMACROS () AS LONG
                
                    LOCAL R AS BYTE, G AS BYTE, B AS BYTE, rgbvalue AS LONG
                    LOCAL S AS STRING
                
                    R = 100
                    G = 200
                    B = 12
                
                    rgbvalue = RGB(R,G,B)
                
                    S = USING$ ("Red= #" & $CRLF & "Green= #" & $CRLF & "Blue=#", _ 
                        mGetRed(rgbvalue), mgetGreen(rgbvalue), mGetBlue(rgbvalue))
                
                    MSGBOX S
                END FUNCTION
                MCM
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Wow, thanks for all the feedback, guys!

                  This here pretty much clarifies things for me:

                  "What seems like wierd numbers (like "RGB(10,10,10)=657930 (very unexpected)") is a consequence of viewing as decimal. In this case:
                  657930 = 10 + (10 * 256) + (10 * 65536)"

                  And the methods you all outlined should come in handy, too!

                  Thank you very much.

                  Comment


                  • #10
                    Dale,

                    Thanks. PBs functions do use BGR. What I had in mind, and should have pointed out, was HTML, which uses RGB.

                    ADDED: Some API functions use the RGB format as well. PB has a function that converts between the two formats called BGR. From the help file: “The BGR function translates an RGB value to its BGR equivalent by swapping the first and third bytes and returning the result. ... calling BGR a second time converts a BGR value back to ... RGB format.” So it looks like BGR might better be called ColorSwap.
                    Last edited by Mark Hunter; 3 Jan 2008, 11:14 PM.
                    Politically incorrect signatures about immigration patriots are forbidden. Searching “immigration patriots” is forbidden. Thinking about searching ... well, don’t even think about it.

                    Comment

                    Working...
                    X