ตารางสี tput setaf? วิธีการกำหนดรหัสสี?


79

PS1ฉันอยู่ในกระบวนการของการระบายสีขั้วของฉัน

ฉันกำลังการตั้งค่าตัวแปรสีใช้tput; ตัวอย่างเช่นนี่คือสีม่วง:

PURPLE=$(tput setaf 125)

คำถาม:

ฉันจะค้นหารหัสสี (เช่น125) ของสีอื่น ๆ ได้อย่างไร

มีคู่มือตารางสี / แผ่นโกงอยู่ที่ไหนสักแห่ง?

ฉันแค่ไม่แน่ใจว่า125คืออะไร... มีวิธีใดที่จะใช้สีฐานสิบหกและแปลงเป็นตัวเลขที่setafสามารถใช้ได้หรือไม่?


คำตอบ:


153

นับของสีที่มีการ tput tput colorsจะได้รับจาก

หากต้องการดูสีพื้นฐาน 8 สี (ตามที่ใช้โดยsetfในเทอร์มินัล urxvt และsetafในเทอร์มินัล xterm):

$ printf '\e[%sm▒' {30..37} 0; echo           ### foreground
$ printf '\e[%sm ' {40..47} 0; echo           ### background

และมักจะตั้งชื่อตามนี้:

Color       #define       Value       RGB
black     COLOR_BLACK       0     0, 0, 0
red       COLOR_RED         1     max,0,0
green     COLOR_GREEN       2     0,max,0
yellow    COLOR_YELLOW      3     max,max,0
blue      COLOR_BLUE        4     0,0,max
magenta   COLOR_MAGENTA     5     max,0,max
cyan      COLOR_CYAN        6     0,max,max
white     COLOR_WHITE       7     max,max,max

หากต้องการดูส่วนขยาย 256 สี (ตามที่ใช้โดยsetafใน urxvt):

$ printf '\e[48;5;%dm ' {0..255}; printf '\e[0m \n'

หากคุณต้องการตัวเลขและผลลัพธ์ที่สั่งซื้อ:

#!/bin/bash
color(){
    for c; do
        printf '\e[48;5;%dm%03d' $c $c
    done
    printf '\e[0m \n'
}

IFS=$' \t\n'
color {0..15}
for ((i=0;i<6;i++)); do
    color $(seq $((i*36+16)) $((i*36+51)))
done
color {232..255}

256 แผนภูมิสีตามลำดับกำกับด้วยดัชนี


16 ล้านสีต้องการรหัสค่อนข้างน้อย (บางคอนโซลไม่สามารถแสดงได้)
พื้นฐานคือ:

fb=3;r=255;g=1;b=1;printf '\e[0;%s8;2;%s;%s;%sm▒▒▒ ' "$fb" "$r" "$g" "$b"

fbเป็นหรือ front/back3/4

การทดสอบความสามารถคอนโซลของคุณอย่างง่าย ๆ เพื่อนำเสนอสีมากมายคือ:

for r in {200..255..5}; do fb=4;g=1;b=1;printf '\e[0;%s8;2;%s;%s;%sm   ' "$fb" "$r" "$g" "$b"; done; echo

เส้นสีแดงจางจากเข้มขึ้นไปเบา (จากซ้ายไปขวา) มันจะนำเสนอเส้นสีแดงที่มีการเปลี่ยนแปลงเล็กน้อยในเสียงจากซ้ายไปขวา หากมองเห็นการเปลี่ยนแปลงเล็กน้อยนั้นคอนโซลของคุณมีความสามารถ 16 ล้านสี

แต่ละr, gและ bเป็นค่าตั้งแต่ 0 ถึง 255 สำหรับ RGB (แดง, เขียว, น้ำเงิน)

หากประเภทคอนโซลของคุณรองรับสิ่งนี้รหัสนี้จะสร้างตารางสี:

mode2header(){
    #### For 16 Million colors use \e[0;38;2;R;G;Bm each RGB is {0..255}
    printf '\e[mR\n' # reset the colors.
    printf '\n\e[m%59s\n' "Some samples of colors for r;g;b. Each one may be 000..255"
    printf '\e[m%59s\n'   "for the ansi option: \e[0;38;2;r;g;bm or \e[0;48;2;r;g;bm :"
}
mode2colors(){
    # foreground or background (only 3 or 4 are accepted)
    local fb="$1"
    [[ $fb != 3 ]] && fb=4
    local samples=(0 63 127 191 255)
    for         r in "${samples[@]}"; do
        for     g in "${samples[@]}"; do
            for b in "${samples[@]}"; do
                printf '\e[0;%s8;2;%s;%s;%sm%03d;%03d;%03d ' "$fb" "$r" "$g" "$b" "$r" "$g" "$b"
            done; printf '\e[m\n'
        done; printf '\e[m'
    done; printf '\e[mReset\n'
}
mode2header
mode2colors 3
mode2colors 4

แผนภูมิสีพื้นหน้าตัวอย่างพร้อมดัชนีเป็นป้ายกำกับ

แผนภูมิสีพื้นหลังตัวอย่างพร้อมดัชนีเป็นป้ายกำกับ

ในการแปลงค่าสีฐานสิบหกไปเป็นดัชนีสี 0-255 ที่ใกล้ที่สุด:

fromhex(){
    hex=${1#"#"}
    r=$(printf '0x%0.2s' "$hex")
    g=$(printf '0x%0.2s' ${hex#??})
    b=$(printf '0x%0.2s' ${hex#????})
    printf '%03d' "$(( (r<75?0:(r-35)/40)*6*6 + 
                       (g<75?0:(g-35)/40)*6   +
                       (b<75?0:(b-35)/40)     + 16 ))"
}

ใช้เป็น:

$ fromhex 00fc7b
048
$ fromhex #00fc7b
048

วิธีค้นหาหมายเลขสีที่ใช้ในรูปแบบสี HTML :

#!/bin/dash
tohex(){
    dec=$(($1%256))   ### input must be a number in range 0-255.
    if [ "$dec" -lt "16" ]; then
        bas=$(( dec%16 ))
        mul=128
        [ "$bas" -eq "7" ] && mul=192
        [ "$bas" -eq "8" ] && bas=7
        [ "$bas" -gt "8" ] && mul=255
        a="$((  (bas&1)    *mul ))"
        b="$(( ((bas&2)>>1)*mul ))" 
        c="$(( ((bas&4)>>2)*mul ))"
        printf 'dec= %3s basic= #%02x%02x%02x\n' "$dec" "$a" "$b" "$c"
    elif [ "$dec" -gt 15 ] && [ "$dec" -lt 232 ]; then
        b=$(( (dec-16)%6  )); b=$(( b==0?0: b*40 + 55 ))
        g=$(( (dec-16)/6%6)); g=$(( g==0?0: g*40 + 55 ))
        r=$(( (dec-16)/36 )); r=$(( r==0?0: r*40 + 55 ))
        printf 'dec= %3s color= #%02x%02x%02x\n' "$dec" "$r" "$g" "$b"
    else
        gray=$(( (dec-232)*10+8 ))
        printf 'dec= %3s  gray= #%02x%02x%02x\n' "$dec" "$gray" "$gray" "$gray"
    fi
}

for i in $(seq 0 255); do
    tohex ${i}
done

ใช้เป็น ("พื้นฐาน" คือ 16 สีแรก "สี" เป็นกลุ่มหลัก "สีเทา" เป็นสีเทาสุดท้าย):

$ tohex 125                  ### A number in range 0-255
dec= 125 color= #af005f
$ tohex 6
dec=   6 basic= #008080
$ tohex 235
dec= 235  gray= #262626

ฟังก์ชั่น fromhex ของคุณยอดเยี่ยมมาก! ขอบคุณมาก!
mhulse

Lovin' fromhexขอบคุณอีกครั้ง! นอกจากนี้ผมได้เพิ่มการตรวจสอบสำหรับ #ข้อเสนอแนะ?
mhulse

1
ใช่การลบ '#' นำหน้าเป็นการป้องกันที่สมเหตุสมผล hex=${1#"#"}ผมพบว่าง่ายมากที่จะใช้ มันจะลบอะไรถ้า$1ไม่มี#และลบถ้ามันมีอยู่ ดูรหัสปรับปรุงของฉัน

ดี! กระชับยิ่งขึ้น อัปเดตรหัสของฉันตอนนี้ ขอขอบคุณ!!!!
mhulse

โปรดทราบว่าอย่างน้อยในรุ่น xterm ของ\e[0;%s8;2;%s;%s;%smฉันสีไม่ให้ฉัน 16M เพียงสีในจานสี 240 สีที่ใกล้เคียงกับ rgb ที่ร้องขอ
Stéphane Chazelas

14

คำตอบสั้น ๆ คือคุณสามารถค้นหาในตารางสีและจับคู่กับจำนวนสี

คำตอบยาวคือการทำแผนที่ที่ถูกต้องขึ้นอยู่กับขั้ว -

นี่125คือพารามิเตอร์ของลำดับ escape ที่อ้างถึงsetafในคำอธิบายเทอร์มินัล tputแนบความหมายเฉพาะกับหมายเลข ที่จริงแล้วขึ้นกับเทอร์มินัลอีมูเลเตอร์เป็นพิเศษ

ในขณะที่กลับมา ANSI กำหนดรหัสสำหรับ 8 สีและมีสองรูปแบบสำหรับการกำหนดหมายเลขเหล่านั้น ทั้งสองจะเห็นในรายละเอียดขั้วบางส่วนเป็นคู่หรือsetf/setb setaf/setabเนื่องจากหลังมีความหมายแฝงของ "สี ANSI" คุณจะเห็นว่ามีการใช้งานบ่อยขึ้น อดีต (setf / setb) เปลี่ยนคำสั่งซื้อเป็นสีแดง / สีน้ำเงินตามที่ระบุไว้ใน ncurses คำถามที่พบบ่อยทำไมสีแดง / สีน้ำเงินเปลี่ยน? แต่ในทั้งสองกรณีชุดรูปแบบได้ถูกสร้างขึ้นเพื่อกำหนดหมายเลขสีเท่านั้น ไม่มีความสัมพันธ์ที่กำหนดไว้ล่วงหน้าระหว่างตัวเลขเหล่านั้นกับเนื้อหา RGB

สำหรับเทอร์มินัลอีมูเลเตอร์ที่เฉพาะเจาะจงมีจานสีที่กำหนดไว้ล่วงหน้าซึ่งสามารถระบุได้ง่ายพอ - และสามารถตั้งโปรแกรมโดยใช้ลำดับการหลีกเลี่ยงเหล่านี้ ขณะนี้ไม่มีมาตรฐานที่เกี่ยวข้องและคุณจะเห็นความแตกต่างระหว่างการเลียนแบบขั้วตามที่ระบุไว้ใน xterm คำถามที่พบบ่อยฉันไม่ชอบร่มเงาของสีฟ้า

อย่างไรก็ตามการประชุมมักจะสับสนกับมาตรฐาน ในการพัฒนา xterm ในช่วง 20 ปีที่ผ่านมามันรวมสี ANSI (8) ปรับaixtermคุณสมบัติ (16) สีเพิ่มส่วนขยายสำหรับ 88- และ 256 สี ผู้พัฒนารายอื่นได้รับการรับรองจากส่วนใหญ่สำหรับผู้เอาอย่างเครื่องเทอร์มินัลต่างๆ ที่สรุปไว้ในคำถามที่พบบ่อย xterm ทำไมไม่สร้าง "xterm" ให้เท่ากับ "xterm-256color" .

ซอร์สโค้ด xterm มีสคริปต์สำหรับแสดงสีเช่นใช้ลำดับการหลีกเลี่ยงเดียวกับที่tputจะใช้

คุณอาจพบว่าคำถาม / คำตอบนี้มีประโยชน์เช่นกัน: ค่า RGB ของสีในดัชนี Ansi Extended colours (17-255)


ขอบคุณมากสำหรับความช่วยเหลือของคุณโธมัสฉันซาบซึ้งจริงๆ! ฉันใช้งาน Mac อยู่บน Mac / OS X คำอธิบายของคุณช่วยให้ฉันเข้าใจเพิ่มเติมเกี่ยวกับการตั้งค่าของฉัน (ฉันทำสำเนา / วางจำนวนมากจากสีพรอมต์ของผู้อื่นบนเว็บ) ฉันขอขอบคุณที่คุณสละเวลาเขียนคำตอบที่มีรายละเอียดและให้ข้อมูลฉัน :)
mhulse

9

tputยูทิลิตี้ใช้ตารางการค้นหา 256 สีในการพิมพ์8 บิตลำดับ ANSI หลบหนี (เริ่มต้นด้วยEscและ[) ซึ่งทำให้การใช้ความสามารถของสถานีเหล่านี้จึงวนเวียนควบคุมสามารถตีความได้ว่าสี เหล่านี้เป็นชุดที่กำหนดไว้ล่วงหน้าของ 256 สีที่ใช้กันทั่วไปในกราฟิกการ์ด

หากต้องการพิมพ์สีทั้งหมด 256 สีในเทอร์มินัลให้ลองหนึ่งซับต่อไปนี้:

for c in {0..255}; do tput setaf $c; tput setaf $c | cat -v; echo =$c; done

คำแนะนำ: ผนวก| columnเข้ากับรายการคอลัมน์

ตารางค้นหา 256 สีนี้สามารถพบได้ที่หน้า Wikipediaดังต่อไปนี้:

แผนภูมิ;  รหัสหลบหนีของ ANSI;  ตารางค้นหา 256 สี 8 บิตที่ Wikipedia;  โหมด 256 สี - เบื้องหน้า: ESC [38; 5; #m พื้นหลัง: ESC [48; 5; #m


3

ด้วย zsh และในxtermขั้วเหมือน ( xtermและvteขั้วชั่นเช่นgnome-terminal, xfce4-terminal... อย่างน้อย) คุณสามารถทำได้:

$ read -s -t1 -d $'\a' $'c?\e]4;125;?\a' && echo "${c##*;}"
rgb:afaf/0000/5f5f

ทุบตีเทียบเท่า:

read -s -t1 -d $'\a' -p $'\e]4;125;?\a' c && echo "${c##*;}"

(คุณต้องการให้ลำดับ escape เพื่อเคียวรีสีที่จะส่งหลังจากechoปิดการใช้งานเทอร์มินัล(ด้วย-s) มิฉะนั้นการตอบสนองจะถูกแสดงโดยการลงรายการบัญชีบรรทัดครึ่งเวลาดังนั้นการส่งมันเป็นส่วนหนึ่งของreadพรอมต์ ( var?promptใน zsh เช่นเดียวกับใน ksh -p promptในทุบตี))

เพื่อให้ได้คำจำกัดความของสี 125 (นี่คือข้อกำหนด RGB แต่ละหมายเลขคือความเข้มของส่วนประกอบสีแดงสีเขียวและสีน้ำเงินเป็นตัวเลขฐานสิบหกระหว่าง 0 ถึง FFFF)

คุณสามารถทำเช่นเดียวกันสำหรับ 16 สีแรกด้วยxtermcontrolคำสั่ง:

$ xtermcontrol --get-color1
rgb:cdcd/0000/0000

เยี่ยมมากขอบคุณมากสำหรับความช่วยเหลือ! +1
mhulse

@Gilles คุณต้องการให้ส่งคำสั่งผ่านทางพร้อมต์หลังจากปิดใช้งานเสียงสะท้อนของเทอร์มินัล ดูการแก้ไข
Stéphane Chazelas

@ StéphaneChazelasการใช้โปรแกรมเทอร์มินัลอื่น (gnome-terminal) (ซึ่งเป็นเทอร์มินัล xterm) ฉันได้รับรหัสของคุณเพื่อทำงานอย่างถูกต้อง (ทั้งใน bash และ zsh) ผิดปกติพอ: tput colorsรายงาน8แม้ว่าเทอร์มินัลจะสามารถแสดงสีได้ 256 สี นอกจากนี้สี xterm (Konsole) tput colorsจะรายงานเฉพาะ8เมื่อเทอร์มินัลนั้นมีความสามารถในการนำเสนอ 16 ล้านสี (และ 256 สีทั้งหมดในหลักสูตร) และไม่ไม่มี tmux หรือหน้าจอที่อาจ "color" :-) (การเปลี่ยนแปลงนั่นคือ) ผลลัพธ์ (ฉันทราบรายละเอียดนั้น) ในระยะสั้น: รหัสของคุณอาจล้มเหลวในบางขั้ว / คอนโซล

อา tohex เพิ่มคำตอบของฉันนานกว่าที่ฉันคาดไว้เล็กน้อย แต่ 256 สีมีจุดพลิกผันเล็กน้อย

0

ANSI Colours บนเทอมคอนโซล

ทั้งนี้ขึ้นอยู่กับระยะโปรโตคอลชใช้คอนโซลของคุณลำดับอาจจะ: \e[38;5;XXXmหรือ\e[3XXXmที่XXXสอดคล้องกับมาตรฐาน ANSI จำนวน

เพื่อให้แน่ใจว่าคุณใช้ลำดับ ANSI tputขวาคุณต้องใช้

เกี่ยวกับรหัสหลบหนี ANSI ของ Wikipediaฉันเขียนสิ่งนี้:

#!/bin/bash


for ((i=0; i<256; i++)) ;do
    echo -n '  '
    tput setab $i
    tput setaf $(( ( (i>231&&i<244 ) || ( (i<17)&& (i%8<2)) ||
        (i>16&&i<232)&& ((i-16)%6 <(i<100?3:2) ) && ((i-16)%36<15) )?7:16))
    printf " C %03d " $i
    tput op
    (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
        printf "\n" ''
done

สามารถแสดงผลเช่น:

ป้อนคำอธิบายรูปภาพที่นี่

... จากนั้นเพราะฉันเกลียด runnig มากกว่า 200 ส้อมในสคริปต์เล็กน้อยฉันจึงเขียนสิ่งนี้:

#!/bin/bash

# Connector fifos directory
read TMPDIR < <(mktemp -d /dev/shm/bc_shell_XXXXXXX)

fd=3
# find next free fd
nextFd() { while [ -e /dev/fd/$fd ];do ((fd++)) ;done;printf -v $1 %d $fd;}

tputConnector() {
    mkfifo $TMPDIR/tput
    nextFd TPUTIN
    eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)"
    nextFd TPUTOUT
    eval "exec $TPUTOUT<$TMPDIR/tput"
}
myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2
}
tputConnector

myTput op op
myTput "setaf 7" grey
myTput "setaf 16" black
fore=("$black" "$grey")
for ((i=0; i<256; i++)) ;do
    myTput "setab $i" bgr
    printf "  %s%s  %3d  %s" "$bgr" "${fore[ i>231 && i<244||(i<17)&& (i%8<2)||
        (i>16&&i<232)&&((i-16)%6*11+(i-16)/6%6*14+(i-16)/36*10)<58
        ? 1 : 0 ]}" $i "$op"
    (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
        printf "\n" ''
done

ด้วยส้อมเดียวเท่านั้น! ผลลัพธ์เดียวกัน แต่เร็วกว่ามาก!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.