在 UNIX shell 脚本中将十六进制颜色转换为十进制 RGB 值

发布于 2024-12-02 17:50:23 字数 143 浏览 1 评论 0原文

我确信有人已经解决了这个问题:有什么简单且便携的方法可以将十六进制颜色值(从 000000 到 FFFFFF 的任何值)转换为 0 到 255 之间的 3 个十进制值。(如果您不熟悉颜色如何转换)传统上用 HTML 表示,前两个十六进制数字是第一个十进制数字,依此类推。)

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

只为一人 2024-12-09 17:50:23
$ 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

如果您不愿意使用 bash 进行子字符串扩展,我仍然会使用 printf 进行转换。

$ 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.

天邊彩虹 2024-12-09 17:50:23

您可以使用像这样的脚本:

#!/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

并像这样使用它:

./hextorgb.sh "11001A"

产生像这样的输出:

17 0 26

它可以通过测试参数等来改进,但它可以满足您的要求。

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.

回忆凄美了谁 2024-12-09 17:50:23

如果您需要此脚本的 POSIX 兼容版本来处理更有效的 CSS 十六进制颜色格式(即:带 alpha 通道的 4 部分 #AABBCCDD、3 字符快捷方式 #FFF) ,这应该可以解决问题:

#!/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 "$@"

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 "$@"
尘曦 2024-12-09 17:50:23
#!/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"
#!/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"
残疾 2024-12-09 17:50:23

我知道这个问题已经很老了,但添加一个轶事;

或者,如果您想将 RGB 转换为十六进制,您可以执行以下操作:

#!/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

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
瑾夏年华 2024-12-09 17:50:23
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}
quot; "/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
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}
quot; "/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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文