背景

背景

背景

在 MetaPost 中,可以通过调用透明度函数来使颜色变亮或变暗。但是,这允许其他颜色透过,这并不总是理想的。有时应该独立于其透明度来使颜色变亮或变暗,方法是更改​​其价值

问题

可以在 MetaPost 中使用乘法来调整颜色,例如:

\definecolor[BaseColour][h=66CEF1]

\startuseMPgraphic{page:ThemeElement}
  color baseColour;
  baseColour := .5 * \MPcolor{BaseColour};
\stopuseMPgraphic

然而,这改变了饱和,也可能是色调也一样。

问题

在 MetaPost 中,如何控制颜色价值饱和, 和色调,独立地?

有关的

以下 ConTeXt 代码至少从概念上说明了我想要在 MetaPost 中做的事情:

\definecolor[BaseColour][h=66CEF1]
\definespotcolor[BaseColourSaturation][BaseColour][s=.625]
\definespotcolor[BaseColourValue][BaseColour][value=.625]
\definespotcolor[BaseColourHue][BaseColour][hue=.625]

MetaPost 应用程序手册定义:

SetupColors( auto-SV, shading-SV, grayscale )

来自邮件列表:

看起来,这些函数在 Evince(我正在使用的 PDF 阅读器)中查看时都会呈现相同的输出。

来自手动的你可以采用一个补充因素:

.7[red,white]

例如:

fill unitsquare scaled 1cm withcolor .7[red,white];

但这还不足以提供足够的控制。

答案1

ConTeXt 具有几种颜色转换功能,这些功能内置于核心中:

  • CMYK 转灰色
  • CMYK 转 RGB
  • 灰色到HSV
  • HSV 转灰色
  • HSV 转 RGB
  • RGB 转 CMYK
  • RGB 转灰色
  • RGB 转 HSV

它们在文件中定义 attr-col.lua。这里我使用Lua函数 hsvtorgb 将 HSV 输入转换为 MetaPost 可以理解的 RGB 值。界面不太美观,但应该可以帮您入门。您可以随意创建 MetaPost 转换定义。

%% macros=mkvi

\starttexdefinition hsvtorgb #h #s #v
  \ctxlua{context("(\letterpercent f, \letterpercent f, \letterpercent f)", attributes.colors.hsvtorgb(#h, #s, #v))}
\stoptexdefinition

\starttext

Hues

\dostepwiserecurse{0}{360}{20}{\dontleavehmode
  \startMPcode
    fill unitcircle scaled 1cm withcolor \hsvtorgb{\recurselevel}{.76}{.76};
  \stopMPcode}

Saturation

\dorecurse{19}{\dontleavehmode
  \startMPcode
    fill unitcircle scaled 1cm withcolor \hsvtorgb{120}{.04*\recurselevel}{.76};
  \stopMPcode}

Value

\dorecurse{19}{\dontleavehmode
  \startMPcode
    fill unitcircle scaled 1cm withcolor \hsvtorgb{120}{.76}{.04*\recurselevel};
  \stopMPcode}

\stoptext

截屏

答案2

这是一个允许普通 Metapost 使用 HSV 颜色的解决方案。

prologues := 3;
outputtemplate := "%j%c.eps";

vardef hsv_color(expr h,s,v) =
    % following wikipedia article on "HSL and HSV"
    save chroma, hh, x, m;
    chroma = v*s;
    hh = h/60;
    x  = chroma * (1-abs(hh mod 2 - 1));
    m  = v - chroma;
    if     hh < 1: (chroma,x,0)+(m,m,m)
    elseif hh < 2: (x,chroma,0)+(m,m,m)
    elseif hh < 3: (0,chroma,x)+(m,m,m)
    elseif hh < 4: (0,x,chroma)+(m,m,m)
    elseif hh < 5: (x,0,chroma)+(m,m,m)
    else:          (chroma,0,x)+(m,m,m)
    fi
enddef;

beginfig(1);
label.rt("Hue",        (-12,96));
label.rt("Saturation", (-12,64));
label.rt("Value",      (-12,32));
for i=0 upto 18:
   fill fullcircle scaled 20 shifted (20i,80) withcolor hsv_color(20i,3/4,3/4);
   fill fullcircle scaled 20 shifted (20i,48) withcolor hsv_color(120,i/25,3/4);
   fill fullcircle scaled 20 shifted (20i,16) withcolor hsv_color(120,3/4,i/25);
endfor
endfig;

beginfig(2);
for h=10 step 10 until 360:
  for s = 0.2 step 0.1 until 1:
     fill fullcircle scaled 20 shifted (100s*right) rotated h  withcolor hsv_color(h,s,1);
  endfor
  label(decimal floor(1/2+h), 110 right rotated h);
endfor
endfig;
end.

第一个示例图如下所示: 在此处输入图片描述

第二个显示的是色轮v=1,色轮上的色度沿h色轮方向变化,越s靠近中间色度越小。

HSV 色轮

所有颜色都是平的:明显的渐变(在橙红色区域尤其明显)是一种视觉错觉。

相关内容