DEV Community

Daily Challenge #158 - RGB To Hex Conversion

dev.to staff on January 10, 2020

The rgb() method is incomplete. Complete the method so that passing in RGB decimal values will result in a hexadecimal representation being returne...
Collapse
 
savagepixie profile image
SavagePixie • Edited

My JavaScript solution, which would look a lot nicer if the TC39 finally added a pipeline operator.

const checkRange = num => Math.min(255, Math.max(num, 0))

const rgb = (...args) => args.slice(0, 3)
    .map(x => checkRange(x)
        .toString(16)
        .toUpperCase()
        .padStart(2, '0'))
    .join('')
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lffg profile image
Luiz Felipe Gonçalves • Edited

String.prototype.padStart would handle the addZeroes trick for you. ;)

Collapse
 
quozzo profile image
Quozzo • Edited

I got really confused when the link opened in Portuguese. I had to check my VPN 😆

Thread Thread
 
lffg profile image
Luiz Felipe Gonçalves

Whoops! Sorry about that. :P Should be fixed now.

Collapse
 
savagepixie profile image
SavagePixie • Edited

I've modified it to use padStart instead of my custom function.

Thanks @lffg and @avalander !

Collapse
 
avalander profile image
Avalander

We have padStart now in strings to add characters to the beginning up to a certain length.

Collapse
 
qm3ster profile image
Mihail Malo • Edited

Nodejs (not web):

const rgb = (...args) => 
  Buffer.from(args).toString('hex') // .toUpperCase() // if you are wasteful xD

Not necessarily actually efficient, but definitely hilarious.

General JS:

const rgb = (...args) =>
  args.reduce((a, x, i) => a + x * 0x100 ** (2 /*or args.length*/ - i), 0)
  .toString(16).toUpperCase().padStart(6, '0')
Collapse
 
celyes profile image
Ilyes Chouia • Edited

My PHP Solution

// round the number to the closest value (255 or 0)
function roundToClosest($color)
{ 
    if($color > 255){
        return 255;
    }elseif($color < 0){
        return 0;
    }
    return $color; 
}

function rgb($r,$g,$b){

    $r = roundToClosest($r);
    $g = roundToClosest($g);
    $b = roundToClosest($b);

    return sprintf("%02X%02X%02X", $r, $g, $b);
}
Collapse
 
aminnairi profile image
Amin

Elm

toHexadecimalLetter : Int -> String
toHexadecimalLetter integer =
    case integer of
        10 ->
            "A"

        11 ->
            "B"

        12 ->
            "C"

        13 ->
            "D"

        14 ->
            "E"

        15 ->
            "F"

        _ ->
            String.fromInt integer

toHexadecimal : Int -> String
toHexadecimal integer =
    let
        clampedInteger  = clamp 0 255 integer
        integerDivision = clampedInteger // 16
        decimalDivision = toFloat clampedInteger / 16.0
        rest            = floor ((decimalDivision - toFloat integerDivision) * 16)
    in
        toHexadecimalLetter integerDivision ++ toHexadecimalLetter rest 

rgb : Int -> Int -> Int -> String
rgb red green blue =
    [red, green, blue]
        |> List.map toHexadecimal
        |> String.join ""

Test.

Collapse
 
craigmc08 profile image
Craig McIlwrath

Haskell, using the word8 type to ensure the inputs are from 0-255.

import Data.Bits
import Data.Word 

hexMap :: (Integral a) => a -> Char
hexMap = ("0123456789ABCDEF"!!) . fromIntegral

toHex :: Word8 -> String
toHex word = let lo = word .&. 15
                 hi = word .&. 240
             in  hexMap lo : hexMap (hi `shift` (-4)) : [] 

rgb :: Word8 -> Word8 -> Word8 -> String
rgb r g b = toHex r ++ toHex g ++ toHex b
Collapse
 
maymeow profile image
Meow

My solution in PHP

<?php

namespace MayMeow\PHPColor;

class Color
{
    /** int $red */
    public $red;

    /** int $green */
    public $green;

    /** int $blue */
    public $blue;

    public function __construct($red, $green, $blue)
    {
        $this->red = $red;
        $this->green = $green;
        $this->blue = $blue;
    }

    /**
     * Method convertToHex
     * Covert given color to string #RRGGBB
     */
    public static function convertToHex(Color $color)
    {
        $red = dechex($color->red);
        if (strlen($red) < 2) $red = '0' . $red; // check string length and add zero if needed

        $green = dechex($color->green);
        if (strlen($green) < 2) $green = '0' . $green;

        $blue = dechex($color->blue);
        if (strlen($blue) < 2) $blue = '0' . $blue;

        return '#' . $red . $green . $blue;
    }

    /**
     * Method convertToRGB
     * Convert given color string back to RGB color values
     */
    public static function convertToRGB($hex)
    {
        $hex = ltrim($hex, "#");

        $red = hexdec(substr($hex, 0, 2));
        $green = hexdec(substr($hex, 2, 2));
        $blue = hexdec(substr($hex, 4, 2));

        return new Color($red, $green, $blue);
    }
}
Collapse
 
herobank110 profile image
David Kanekanian

Python solution, supports 1 or 3 arguments like CSS.

rgb = lambda *_: "#"+eval("'%02X'"+(lambda a:a.pop(len(_)>1)+a.pop())(["%_","*3"]))

print(rgb(255)) # => #FFFFFF
print(rgb(126, 28, 29)) # => #7E1C1D
Collapse
 
nickholmesde profile image
Nick Holmes

In C#, you don't even really need to implement a method for this, as its easily done with string interpolation;

    var rgb  = $"{red:X02}{green:X02}{blue:X02}";

(Useful for unique ad-hoc strings, but usually better factored out to a method anyway)

Collapse
 
dannemanne profile image
Daniel Viklund

Ruby solution

def valid_num(v)
  [[v, 255].min, 0].max
end

def rgb(*args)
  args[0..2].reduce('') { |str, v|
    str << valid_num(v).to_s(16).rjust(2, '0')
  }
end
Collapse
 
vaibhavyadav1998 profile image
Vaibhav Yadav

In Go.

func rgb(r, g, b uint8) string {
    return fmt.Sprintf("#%x%x%x", r, g, b)
}
Collapse
 
dannemanne profile image
Daniel Viklund

Thanks for the tip! I've mostly used string formating for dealing with point numbers in decimals. Need to explore more use cases because the syntax is indeed preferable.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

I'd do this with Uint8Array