I'm sure someone has already solved this problem: what is an easy and portable way to convert a hex color value (anything from 000000 to FFFFFF) to 3 decimal values from 0 to 255. (If you're not familiar with how colors are traditionally represented in HTML, the first two hex digits are the first decimal number, and so forth.)
If you need a POSIX compatible version of this script that handles more valid CSS hex color formats (ie: 4-part with alpha channel #AABBCCDD
, 3 char shortcuts #FFF
), this should do the trick:
#!/bin/sh
##? ~/bin/hex2rgb - convert color hex to rgb
# '#C0FFEE' => 192 255 238
# 'DEADBEEF' => 222 173 190 239
# 'fab' => 255 170 187
__hex2rgb() {
# reset $1 to scrubbed hex: '#01efa9' becomes '01EFA9'
set -- "$(echo "$1" | tr -d '#' | tr '[:lower:]' '[:upper:]')"
START=0
STR=
while (( START < ${#1} )); do
# double each char under len 6 : FAB => FFAABB
if (( ${#1} < 6 )); then
STR="$(printf "${1:${START}:1}%.0s" 1 2)"
(( START += 1 ))
else
STR="${1:${START}:2}"
(( START += 2 ))
fi
echo "ibase=16; ${STR}" | bc
done
unset START STR
}
__hex2rgb "$@"
$ cat hexrgb.sh
#!/bin/bash
hex="11001A"
printf "%d %d %d\n" 0x${hex:0:2} 0x${hex:2:2} 0x${hex:4:2}
$ ./hexrgb.sh
17 0 26
If you are not willing to use bash for substring expansion, I'd still use printf for the conversion.
You can use a script like:
#!/bin/sh
# hextorgb.sh
hexinput=`echo $1 | tr '[:lower:]' '[:upper:]'` # uppercase-ing
a=`echo $hexinput | cut -c-2`
b=`echo $hexinput | cut -c3-4`
c=`echo $hexinput | cut -c5-6`
r=`echo "ibase=16; $a" | bc`
g=`echo "ibase=16; $b" | bc`
b=`echo "ibase=16; $c" | bc`
echo $r $g $b
exit 0
and use it like:
./hextorgb.sh "11001A"
resulting in output like:
17 0 26
It can be improved by testing for arguments and so on, but it does what you want.
bc
; the hex input data must be uppercase. Else it'll bite you in the ass down the line when you give it ff
which is interpreted as the variable ff, which isn't set so it gives you 0. –
Resnatron $0
to $1
–
Urology #!/usr/bin/env bash
hex2rgb() {
hex=$(echo "${1^^}" | sed 's/#//g')
a=$(echo $hex | cut -c-2)
b=$(echo $hex | cut -c3-4)
c=$(echo $hex | cut -c5-6)
r=$(echo "ibase=16; $a" | bc)
g=$(echo "ibase=16; $b" | bc)
b=$(echo "ibase=16; $c" | bc)
echo ${1^^}
echo $r $g $b
}
hex2rgb "#FF0000"
hex2rgb "#00FF00"
hex2rgb "#0000FF"
If you need a POSIX compatible version of this script that handles more valid CSS hex color formats (ie: 4-part with alpha channel #AABBCCDD
, 3 char shortcuts #FFF
), this should do the trick:
#!/bin/sh
##? ~/bin/hex2rgb - convert color hex to rgb
# '#C0FFEE' => 192 255 238
# 'DEADBEEF' => 222 173 190 239
# 'fab' => 255 170 187
__hex2rgb() {
# reset $1 to scrubbed hex: '#01efa9' becomes '01EFA9'
set -- "$(echo "$1" | tr -d '#' | tr '[:lower:]' '[:upper:]')"
START=0
STR=
while (( START < ${#1} )); do
# double each char under len 6 : FAB => FFAABB
if (( ${#1} < 6 )); then
STR="$(printf "${1:${START}:1}%.0s" 1 2)"
(( START += 1 ))
else
STR="${1:${START}:2}"
(( START += 2 ))
fi
echo "ibase=16; ${STR}" | bc
done
unset START STR
}
__hex2rgb "$@"
I know this question is quite old but to add an anecdote;
alternatively, if you wanted to convert rgb to hex you could do a little something like:
#!/bin/sh
# rgbtohex.sh
f="$1,"
focus=0
start=0
until [ "$limit" == "3" ]
do
focus=$((focus+1))
if [ "${f:$focus:1}" == "," ]
then
limit=$((limit+1))
length=$(($focus-$start))
let c$limit="${f:start:length}"
start=$((focus+1))
fi
done
r=`echo "obase=16; $c1" | bc`
r2=`echo "obase=16; $c2" | bc`
r3=`echo "obase=16; $c3" | bc`
if [ "${r:1:2}" == "" ]
then r=0$r
fi
if [ "${r2:1:2}" == "" ]
then r2=0$r2
fi
if [ "${r3:1:2}" == "" ]
then r3=0$r3
fi
echo $r$r2$r3
The simplest, but not compact, way to convert a color value is to
use the constant = ("1.00, 255 FF" "..., .. .." "0.0, 0 00").
The example in the last line of the script converts the string
to a hexadecimal color value from the file /usr/share/X11/rgb.txt.
Using the search command grep -A in the case of rgb 0.00.
#!/usr/bin/env bash
# rgb; X11; hex; --> HEX.
# ${BASH} ./rgb-hex.sh or "{ 0.0, 0.0, 0.0 }"; or "magenta"; or #ffffff
# Otherwise, a value of the type "#000" will be returned, as well as "empty" or "error".
# В іншому випадку буде повернуто значення типу "#000", а також "порожнє" або "помилка".
NO_ARGS=0
E_OPTERROR=65
if [ $# -eq "$NO_ARGS" ] # Script called without arguments?
then
echo "Directions for use: `basename $0` options \"{ 0.0, 0.0, 0.0 }\""
exit $E_OPTERROR # If there are no arguments, exit with a message
fi
rgbinhex (){
IN="${1:-{ 0.0, 0.0, 0.0 }}"
printf -v IN "${IN//[\{\ \}]/}0"
IN="${IN//[,]/0,}"
IN="$( grep -Eo '[1]*\.[0-9]{,2}' \
<<<"${IN}" | tr -d \. | sed 's/^0//g;' )"
printf -v R "$( head -n1 <<<"${IN}" | tail -n1 )"
printf -v G "$( head -n2 <<<"${IN}" | tail -n1 )"
printf -v B "$( head -n3 <<<"${IN}" | tail -n1 )"
printf '\x23%02X%02X%02X\n' "$(( R * 255 / 100 ))" \
"$(( G * 255 / 100 ))" "$(( B * 255 / 100 ))"
}
[[ ${1} = \{*\,* ]] && rgbinhex "${1}" \
&& \
exit 0
[[ ${1} = \#[[:xdigit:]]* ]] && printf '%s\n' "${1}" \
| tr '[:lower:]' '[:upper:]' \
&& \
exit 0
[[ ${1} = "" ]] && printf '%s\n' "#000" \
&& \
exit 0
[[ ${1} = [[:alnum:]\ ]* ]] && printf '#%02X%02X%02X\n' \
$(grep -Eiwm1 "\s\s*${1}$" "/usr/share/X11/rgb.txt" \
| awk '{print $1,$2,$3}') \
&& \
exit 0
exit 0
For checking and control you can use the wonderful GUI script nf yad:
~$ yad --window-icon=color-selection --title=Color-Selection --color --gtk-palette --expand-palette --palette=/usr/share/X11/rgb.txt --scroll
© 2022 - 2024 — McMap. All rights reserved.