初歩のシェルスクリプトで遊ぶ[端末の256色カラーセレクタ(1)]
寄せ集めででっち上げた256色サンプル画像作成スクリプト
端末用の256色のサンプル画像。
色の一覧から、文字色と背景色を拾うスクリプトを作っとるんすが、そのスクリプト用のシェル関数を組み合わせた、サンプル画像作成スクリプトです。
なんだかんだで、使うのって、手間かけたものより、画像一枚だったりするんすよね。
カラーセレクタのスクリプト自体はだいたい出来てるんだけれど、まだ迷ってるところもあるんで、まずはこれから。
以下のスクリプト自体は、ただの色サンプルに余計なことをやりすぎ、ではあるんだけれど。
ひとつだけ機能
このスクリプトに付加した機能が一つだけ。
色番号の数字は、黒か、白かを自動で切り替えてます。この閾値の指定です。
RGBの値から明るさを出すのに、「Y=0.3R+0.59G+0.11B」で計算してます。このYのどこで、黒数字と白数字を切り分けるかの指定が可能です。
つまり、文字を白にするなら、背景色はこの色にするとコントラストを確保できますよと。そういう判断の参考にできる。
#!/bin/sh #!/bin/dash #!/bin/busybox sh #!/usr/bin/posh #!/usr/bin/yash #!/bin/bash #!/usr/bin/ksh #!/usr/bin/zsh # ======================================================================================== # ■ 端末256色 色と番号の一覧画像作成 v1.0 # https://twitter.com/beta_reverse_2 # ======================================================================================== # # カラーリスト表の何番を表示するのか colorTableNo=${1:-0} # 表示幅は何文字分か imageWidth=${2:-120} # 色番号の数字は、黒い文字と白い文字、どちらで表示するのか # 明るさ[0-255]の間で、どこを境目に白文字と黒文字を切り替えるのか fontThreshold=${3:-127} # PATH="./lib:${PATH}" # ====[shMerge<disable>]==== #_shMergeDisabled # # ====[shMerge]==== colorTableListSh 20201017_191014 colorTableListSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 引数に数字を与えると、その番号のカラーパレットデータを出力する # パレットデータの数字は「0-255」 # 行のデータはタブ区切りにする # 1行に入れる数値データの数は、360の約数にする # 行数に制限は無いが、端末表示に収まる行数に。 # 「0-255」を、すべて必ず1回ずつ使わなければならない。 # 同じ数字を複数回使ってはいけない。 # カスタマイズするなら、既存のカラーパレットをベースにして、行単位で入れ替えると簡単。 # カラーパレット_色相HSL 色の濃さ => 明るさ => 色合い Palette0='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 95 101 65 66 60 96 138 144 108 109 103 139 131 137 143 107 71 72 73 67 61 97 133 132 181 187 151 152 146 182 174 180 186 150 114 115 116 110 104 140 176 175 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 52 58 22 23 17 53 88 94 100 64 28 29 30 24 18 54 90 89 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 217 223 229 193 157 158 159 153 147 183 219 218 224 230 194 195 189 225' # HSV S=>V=>H Palette1='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 224 230 194 195 189 225 181 187 151 152 146 182 138 144 108 109 103 139 95 101 65 66 60 96 217 223 229 193 157 158 159 153 147 183 219 218 174 180 186 150 114 115 116 110 104 140 176 175 131 137 143 107 71 72 73 67 61 97 133 132 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 52 58 22 23 17 53 88 94 100 64 28 29 30 24 18 54 90 89 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197' # カラーパレット_色番号順 Palette2='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231' Palette3='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 52 58 22 23 17 53 88 94 100 64 28 29 30 24 18 54 90 89 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 95 101 65 66 60 96 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197 131 137 143 107 71 72 73 67 61 97 133 132 138 144 108 109 103 139 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 174 180 186 150 114 115 116 110 104 140 176 175 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 181 187 151 152 146 182 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 217 223 229 193 157 158 159 153 147 183 219 218 224 230 194 195 189 225' Palette4='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 52 58 22 23 17 53 95 101 65 66 60 96 88 94 100 64 28 29 30 24 18 54 90 89 138 144 108 109 103 139 131 137 143 107 71 72 73 67 61 97 133 132 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 181 187 151 152 146 182 174 180 186 150 114 115 116 110 104 140 176 175 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 224 230 194 195 189 225 217 223 229 193 157 158 159 153 147 183 219 218 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197' # 存在するデータの番号を入力されたとき、そのデータを出力して、exit 0 # 存在しないデータの番号を入力されたとき、exit 1 eval 'XX=`echo "${Palette'${1:-0}'}"`' if test -n "${XX}" ; then eval 'echo "${Palette'${1:-0}'}"' exit 0 else exit 1 fi # [EOF] ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256matrixToViewCodeSh 20201017_191014 ansi256matrixToViewCodeSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # カラーパレット表を読み込んで、パレットを端末表示するためのデータを作成する。 # 表示幅(文字数)は指定できる。 # 一行に指定されるパレットの数が増減しても、表示幅を同じ幅に揃える。 roundSh(){ ( Width=${1:?'横幅指定が必要'} Part=${2:?'分割数指定が必要'} # 余った文字数 Remaind=$(( ${Width} % ${Part} )) # 余った文字を振り分ける行番号リスト addLines='' NN=1 while test ${NN} -le ${Remaind} ; do addLines="${addLines}$(( ( ${Part} * ${NN} ) / ( ${Remaind} + 1 ) + 1 )) " NN=$(( ${NN} + 1 )) done #echo "${addLines}" # 【debug】 partNo='1' while test "${partNo}" -le "${Part}" ; do addLineFlag='false' # ${partNo}が 指定値と同じなら フラグtrue while read addLine ; do if test -z "${addLine}" ; then continue elif test "${partNo}" -eq "${addLine}" ; then addLineFlag='true' fi done << ____ADD_LINES ${addLines} ____ADD_LINES #printf '%d:' "${partNo}" # 【debug】 # trueのとき1加算 if ${addLineFlag} ; then echo $(( ${Width} / ${Part} + 1 )) else echo $(( ${Width} / ${Part} )) fi partNo=$(( ${partNo} + 1 )) done exit 0 ) } # 全体の横幅は何文字にするのか Cols=${1:-78} while read LINE ; do eval set -- ${LINE} addChars=`roundSh ${Cols} ${#}` NUM=0 while read NN ; do NUM=$(( ${NUM} + 1 )) eval 'wordLength_'${NUM}'=${NN}' done << ____add ${addChars} ____add NUM=0 for Index in ${@} ; do NUM=$(( ${NUM} + 1 )) # wordLength インデックスカラーを表示する幅を文字数で eval 'wordLength=${wordLength_'${NUM}'}' # Index インデックス番号 # wordLength 表示幅を文字数で echo "${Index} ${wordLength}" done echo '0 -1' done ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256_numToRGBsh 20201017_191014 ansi256_numToRGBsh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 標準入力から「0-255」の数字を入力すると、 # RGB256階調の数値を出力する。 # 「0-16」のときは「__」を出力する。(「--」「-」は不適切 「set --」関係) while read Index ; do RR='__' GG='__' BB='__' if test "${Index}" -ge 0 && test "${Index}" -le 15 ; then echo "${RR} ${GG} ${BB} ${Index}" elif test "${Index}" -ge 16 && test "${Index}" -le 231 ; then numTo256Func(){ # ${1}:代入する変数名 RR,GG,BBのいずれか # ${2}:「0-5」の数値 RGBのレベル指定 case "${2}" in ( 0 ) eval ${1}'=0' ;; ( 1 ) eval ${1}'=95' ;; ( 2 ) eval ${1}'=135' ;; ( 3 ) eval ${1}'=175' ;; ( 4 ) eval ${1}'=215' ;; ( 5 ) eval ${1}'=255' ;; esac } numTo256Func RR $(( ( ${Index} - 16 ) / 36 )) numTo256Func GG $(( ( ( ${Index} - 16 ) % 36 ) / 6 )) numTo256Func BB $(( ( ( ${Index} - 16 ) % 36 ) % 6 )) echo "${RR} ${GG} ${BB} ${Index}" elif test "${Index}" -ge 232 && test "${Index}" -le 255 ; then RR=$(( ( ( ${Index} - 232 ) * 10 ) + 8 )) GG="${RR}" BB="${RR}" echo "${RR} ${GG} ${BB} ${Index}" fi done ) } # ====[shMerge</ins>]==== # 奇数行は1,偶数行は-1 OddEven='1' colorTableListSh ${colorTableNo} | # 色番号表を呼び出す while read tableRow ; do # 行を2行ずつ出力する echo "${tableRow}" echo "${tableRow}" done | ansi256matrixToViewCodeSh ${imageWidth} | # 一色一色の表示横幅を計算 while read Palette Nums ; do # ----------------------------------------------------↓ # Palette 色番号[0-255] # Nums 色の表示幅文字数 # Numsが負ならば改行する if test ${Nums} -le -1 ; then printf '\033[0m\n' OddEven=$(( ${OddEven} * -1 )) continue fi # RGBの値を取得 RGBから明るさYを計算 # Y = 0.3R + 0.59G + 0.11B RGB=`echo "${Palette}" | ansi256_numToRGBsh ` RR=`echo "${RGB}" | cut -f 1` GG=`echo "${RGB}" | cut -f 2` BB=`echo "${RGB}" | cut -f 3` if YY=`expr '(' 30 '*' ${RR} + 59 '*' ${GG} + 11 '*' ${BB} ')' / 100 2>/dev/null` ; then # もしRR,GG,BBが数値なら、YYを計算 true else # RR,GG,BBが数値でないなら、-1を入れておく YY='-1' fi case ${OddEven} in # ---------------------------------------------------------------------- ( '1' ) # 奇数行 # ---------------------------------------------------------------------- #printf "\033[48;5;${Palette}m%${Nums}s" "${YY}" # 明るさYを表示する printf "\033[48;5;${Palette}m%${Nums}s" ' ' ;; # ---------------------------------------------------------------------- ( '-1' ) # 偶数行 # ---------------------------------------------------------------------- if test "${YY}" -eq -1 ; then # システムカラー printf "\033[48;5;${Palette}m%"$(( ${Nums} - 2 ))"s\033[97;40m%2d" ' ' "${Palette}" elif test "${YY}" -le ${fontThreshold} ; then # 明るさが ?/255 以下なら白文字に printf "\033[38;5;231m\033[48;5;${Palette}m%${Nums}s" "${Palette}" elif test "${YY}" -gt ${fontThreshold} ; then # 閾値以上なら、黒文字に printf "\033[38;5;16m\033[48;5;${Palette}m%${Nums}s" "${Palette}" else exit 2 fi ;; esac done # ----------------------------------------------------------------------------↑