How to convert Int to R,G,B,Trans?

Widget

Well-Known Member
Licensed User
Longtime User
If I have a Color which is an Int, how to I extract the three R,G,B colors (0..255) as well as the transparency (0..255)?

TIA
Widget
 

alfcen

Well-Known Member
Licensed User
Longtime User
Here a general reuseble means:

B4X:
Sub Process_Globals
   Type clr(a As Int, r As Int, g As Int, b As Int)
   Dim cols As clr
End Sub


SplitColors(thisColor)
a = cols.a
r = cols.r
g = cols.g
b = cols.b

Sub SplitColors(x As Long)
   cols.Initialize
   Dim a, r, g, b As Int
   Dim a0, r0, g0 As Long
   cols.a = Floor(x / Power(2,24))
   r0 = x Mod Power(2,24)
   cols.r = Floor(r0 / Power(2,16))
   g1 = r0 Mod Power(2,16)
   cols.g = Floor(g0 / Power(2,8))
   cols.b = cols.g Mod Power(2,8)
End Sub
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
Alfcen,
Thanks for the attempt, but I wasn't able to get SplitColors to work reliably. I tried something like it last night using Mod and got similar results. It is not as easy as it looks because Color can be negative.

I finally had to use IntsToBytes() from the ByteConverter library. Here is what I finally ended up with.

B4X:
Sub Globals
  Type TARGBColor(Alpha, Red, Green, Blue As Int)
End Sub

Sub CnvtByteToInt(  aByte As Byte) As Int
  Dim Num As Int
  Num = aByte
  If aByte < 0 Then Num = Num + 256
  Return Num
End Sub

Sub GetColors(    aColor As Int)
  Dim Conv     As ByteConverter   'From ByteConverter library
  Dim bytes(8) As Byte
   
  Conv.LittleEndian = False        'Force it to False so we are sure
  bytes = Conv.IntsToBytes(Array As Int(aColor))
   
  Dim ARGBColor As TARGBColor
  ARGBColor.Initialize
   
  ARGBColor.Alpha = CnvtByteToInt(Bytes(0))
  ARGBColor.Red   = CnvtByteToInt(Bytes(1))
  ARGBColor.Green = CnvtByteToInt(Bytes(2))
  ARGBColor.Blue  = CnvtByteToInt(Bytes(3))
  Log("[GetColors] "&ARGBColor)
  Return ARGBColor
End Sub

I have no idea why B4A doesn't have a built-in function to do this because we are working with colors, RGB and alpha all the time.

Widget
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Here is another solution:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    Dim argb() As Int
    argb = GetARGB(Colors.Transparent)
    Log("A = " & argb(0))
    Log("R = " & argb(1))
    Log("G = " & argb(2))
    Log("B = " & argb(3))
End Sub

Sub GetARGB(Color As Int) As Int()
    Dim res(4) As Int
    res(0) = Bit.UnsignedShiftRight(Bit.And(Color, 0xff000000), 24)
    res(1) = Bit.UnsignedShiftRight(Bit.And(Color, 0xff0000), 16)
    res(2) = Bit.UnsignedShiftRight(Bit.And(Color, 0xff00), 8)
    res(3) = Bit.And(Color, 0xff)
    Return res
End Sub
 
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks for this post, Erel,
I'm getting differing results when I create an INT value of a Windows 7 color as follows:
VB.NET
B4X:
Dim Colr as integer = System.Drawing.ColorTranslator.ToWin32(Color.Red)

B4A
B4X:
'returns a color from an integer
Sub GetARGB(Color As Int) As Int()
    Dim res(4) As Int
    res(0) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff000000), 24)    'A (transparency)
    res(1) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff0000), 16)    'R
    res(2) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff00), 8)        'G
    res(3) = Bit.AND(Color, 0xff)                                    'B
    Return res
End Sub

When I use the GetARGB array as follows on the Android tablet:
B4A
B4X:
L1Colr = Fn.getargb(Colr)
rt.color2(Colors.RGB(L1Colr(1), L1Colr(2), L1Colr(3)), "{1}")

I do not get the same color or even close... For example red on the PC is light blue or lavender...
Any advice?
Thanks
Rusty

For those who would like an answer:
In the PC, the value is: (0)- alpha (1)-Red (2)-Green (3)-Blue
In Android, the result of the above featured getARGB needs to load the array inverted (see below and note the res(3)...2, 1, 0 array load):

B4X:
'returns a color from an integer
Sub GetARGB(Color As Int) As Int()
    Dim res(4) As Int
    res(3) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff000000), 24)    'B
    res(2) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff0000), 16)    'G
    res(1) = Bit.UnsignedShiftRight(Bit.AND(Color, 0xff00), 8)        'R
    res(0) = Bit.AND(Color, 0xff)                                    'A (transparency)
    Return res
End Sub
in order to be able to match the integer storage from the PC (Windows 7, Visual Studio)
Regards,
Rusty
 
Last edited:
Upvote 0
Top