在 LaTeX 中,可以使用以下命令定义颜色:
\definecolor{somecolor}{RGB}{0,42,14}
我想知道是否可以获取给定颜色的红色、绿色和蓝色通道的值,因此类似于:
\greenc{somecolor} %result is 42
然后可以使用它来执行算术运算,例如通过 PGF/Tikz。
答案1
对于一个“简单”的问题来说,也许有点太过麻烦,但是这提取了颜色规范的浮点值。
改良版:
将浮点值四舍五入为整数——当然不是万无一失的!
基本解释:extractcolorspecs
在命令中生成模型和颜色规范,后者给出一个浮点值的 CSV 列表,该列表必须拆分。我选择使用expl3
语法来轻松拆分它并将这些值转换为整数。
\documentclass{article}
\usepackage{xcolor}
\definecolor{somecolor}{RGB}{0,42,14}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_commusoft_colorchannels_clist
\fp_new:N \l_greenchannel_fp
\fp_new:N \l_bluechannel_fp
\fp_new:N \l_redchannel_fp
\NewDocumentCommand{\SplitColorChannels}{m}{%
\clist_set:Nx \l_commusoft_colorchannels_clist {#1}
}
\NewDocumentCommand{\ExtractColors}{m}{%
\extractcolorspecs{#1}{\mycolormodel}{\mycolor}
\SplitColorChannels{\mycolor}
\fp_set:Nn \l_greenchannel_fp {\clist_item:Nn \l_commusoft_colorchannels_clist {2}}
\fp_set:Nn \l_redchannel_fp {\clist_item:Nn \l_commusoft_colorchannels_clist {1}}
\fp_set:Nn \l_bluechannel_fp {\clist_item:Nn \l_commusoft_colorchannels_clist {3}}
}
\NewDocumentCommand{\ColorRedChannel}{m}{%
\ExtractColors{#1}
\fp_set:Nn \l_tmpa_fp {\fp_eval:n { \l_redchannel_fp * 256}}
\fp_to_int:N \l_tmpa_fp
}
\NewDocumentCommand{\ColorGreenChannel}{m}{%
\ExtractColors{#1}
\fp_set:Nn \l_tmpa_fp {\fp_eval:n { \l_greenchannel_fp * 256}}
\fp_to_int:N \l_tmpa_fp
}
\NewDocumentCommand{\ColorBlueChannel}{m}{%
\ExtractColors{#1}
\fp_set:Nn \l_tmpa_fp {\fp_eval:n { \l_bluechannel_fp * 256}}
\fp_to_int:N \l_tmpa_fp
}
\ExplSyntaxOff
\begin{document}
Red: \ColorRedChannel{somecolor}
Green: \ColorGreenChannel{somecolor}
Blue: \ColorBlueChannel{somecolor}
\end{document}
答案2
因为你似乎想要可扩展命令,您必须在颜色定义时设置相关位,因为提供的提取/转换功能xcolor
不可扩展。
这里有一种方法,使用两个用于颜色定义的“扩展”命令,即\Xdefinecolor
和\Xcolorlet
。
\documentclass{article}
\usepackage{xcolor,xparse}
\ExplSyntaxOn
\NewDocumentCommand{\Xdefinecolor}{mmm}
{
\definecolor{#1}{#2}{#3}
\str_if_eq:nnTF { #2 } { RGB }
{ % no conversion necessary
\tl_set:cx { l_commusoft_#1_red_tl } { \clist_item:nn { #3 } { 1 } }
\tl_set:cx { l_commusoft_#1_green_tl } { \clist_item:nn { #3 } { 2 } }
\tl_set:cx { l_commusoft_#1_blue_tl } { \clist_item:nn { #3 } { 3 } }
}
{
\convertcolorspec { #2 } { #3 } { RGB } \l_tmpa_clist
\tl_set:cx { l_commusoft_#1_red_tl } { \clist_item:Nn \l_tmpa_clist { 1 } }
\tl_set:cx { l_commusoft_#1_green_tl } { \clist_item:Nn \l_tmpa_clist { 2 } }
\tl_set:cx { l_commusoft_#1_blue_tl } { \clist_item:Nn \l_tmpa_clist { 3 } }
}
}
\NewDocumentCommand{\Xcolorlet}{mm}
{
\colorlet{#1}{#2}
\commusoft_extractcolorspec:nN {#1} \l_tmpa_tl
\exp_last_unbraced:Nf \commusoft_convertcolorspec:nnnN \l_tmpa_tl { RGB } \l_tmpa_clist
\tl_set:cx { l_commusoft_#1_red_tl } { \clist_item:Nn \l_tmpa_clist { 1 } }
\tl_set:cx { l_commusoft_#1_green_tl } { \clist_item:Nn \l_tmpa_clist { 2 } }
\tl_set:cx { l_commusoft_#1_blue_tl } { \clist_item:Nn \l_tmpa_clist { 3 } }
}
\DeclareExpandableDocumentCommand{\getred}{m}
{
\tl_use:c { l_commusoft_#1_red_tl }
}
\DeclareExpandableDocumentCommand{\getgreen}{m}
{
\tl_use:c { l_commusoft_#1_green_tl }
}
\DeclareExpandableDocumentCommand{\getblue}{m}
{
\tl_use:c { l_commusoft_#1_blue_tl }
}
\cs_set_eq:NN \commusoft_convertcolorspec:nnnN \convertcolorspec
\cs_set_eq:NN \commusoft_extractcolorspec:nN \extractcolorspec
\ExplSyntaxOff
\Xdefinecolor{somecolor}{RGB}{0,42,14}
\Xdefinecolor{another}{cmyk}{0.2,0.3,0.4,0.5}
\Xcolorlet{tint}{another!20!red}
\begin{document}
\getred{somecolor}, \getgreen{somecolor}, \getblue{somecolor}
\getred{another}, \getgreen{another}, \getblue{another}
\edef\temp{\getred{another}, \getgreen{another}, \getblue{another}}
\texttt{\meaning\temp}
\getred{tint}, \getgreen{tint}, \getblue{tint}
\colorbox{tint}{\qquad}
\colorbox[RGB]{\getred{tint}, \getgreen{tint}, \getblue{tint}}{\qquad}
\colorbox{somecolor}{\qquad}
\colorbox[RGB]{\getred{somecolor}, \getgreen{somecolor}, \getblue{somecolor}}{\qquad}
\end{document}
请注意,在 的情况下tint
,颜色并不相同,这是由于从cmyk
到 的转换不稳定RGB
(可用的颜色较少)。\edef
显示命令是完全可扩展。