Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
RGB to Hex in Lua
-- passing a table like {255, 100, 20}
function application:rgbToHex(rgb)
local hexadecimal = '0X'
for key, value in pairs(rgb) do
local hex = ''
while(value > 0)do
local index = math.fmod(value, 16) + 1
value = math.floor(value / 16)
hex = string.sub('0123456789ABCDEF', index, index) .. hex
end
if(string.len(hex) == 0)then
hex = '00'
elseif(string.len(hex) == 1)then
hex = '0' .. hex
end
hexadecimal = hexadecimal .. hex
end
return hexadecimal
end
@YellowberryHN
Copy link

YellowberryHN commented Aug 14, 2015

Really good. Thank you very much.

@TJPlaysNow
Copy link

TJPlaysNow commented Oct 27, 2016

This is beautiful! Thanks :D

@red-001
Copy link

red-001 commented Jun 1, 2017

Thanks

@taylan97
Copy link

taylan97 commented Nov 11, 2020

If you want a string you can just string.format("%X", number). If you want specific formatting you can apply width flags (see man printf).

I.e. to make a HTML color code, string.format("#%02X%02X%02X", r, g, b).

@atirut-w
Copy link

atirut-w commented May 3, 2021

An even better version without loops:

function rgbToHex(r,g,b)
    -- EXPLANATION:
    -- The integer form of RGB is 0xRRGGBB
    -- Hex for red is 0xRR0000
    -- Multiply red value by 0x10000(65536) to get 0xRR0000
    -- Hex for green is 0x00GG00
    -- Multiply green value by 0x100(256) to get 0x00GG00
    -- Blue value does not need multiplication.

    -- Final step is to add them together
    -- (r * 0x10000) + (g * 0x100) + b =
    -- 0xRR0000 +
    -- 0x00GG00 +
    -- 0x0000BB =
    -- 0xRRGGBB
    local rgb = (r * 0x10000) + (g * 0x100) + b
    return string.format("%x", rgb)
end

@appgurueu
Copy link

appgurueu commented Jul 12, 2021

This is horrible and unreliable. DO NOT USE THIS:

  1. pairs(rgb) guarantees absolutely no order. If you pass the RGB values as a list {r, g, b}, it will work though, because pairs traverses the list part in order. There's no guarantee this is the case though. Horrible bugs will happen as soon as you pass {r = r, g = g, b = b} tables. For these, absolutely no order is guaranteed. You could be getting RGB if you're lucky, leading you not to discover this undefined behavior, you could also get BGR, GRB, ... though, scratching your head as to why it's not working. To "fix" this, ipairs could be used. Additionally, this is basically a footgun. You can happily pass less than 3 or more than 4 numbers, leading to invalid hex color codes. It will also happily write numbers > 255, screwing up the hex color codes by displacing the following digits and creating a length > 6.

  2. Bad code quality, uneeded complexity. application: which is absolutely useless; self isn't needed. key is unused: _ should be used. Brackets instead of spaces around conditions. The inner while loop basically just does string.format("#%X", value), but a lot slower. The following ifs do the padding, basically string.format("#%02X", value).

  3. Bad performance. This is unnecessarily slow.

Use string.format("#%02X%02X%02X", r, g, b) instead.

Regarding the following:

An even better version without loops:

function rgbToHex(r,g,b)
    - ...
    local rgb = (r * 0x10000) + (g * 0x100) + b
    return string.format("%x", rgb)
end

If you want padding, the last line needs to be return string.format("%06x", rgb).

@atirut-w
Copy link

atirut-w commented Jul 12, 2021

If you want padding, the last line needs to be return string.format("%06x", rgb).

Do you know where can I find a list of formattings and options for C-style string formatting?

@appgurueu
Copy link

appgurueu commented Jul 12, 2021

If you want padding, the last line needs to be return string.format("%06x", rgb).

Do you know where can I find a list of formattings and options for C-style string formatting?

What about https://en.wikipedia.org/wiki/Printf_format_string?

@atirut-w
Copy link

atirut-w commented Jul 12, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment