elisp生成渐变XPM图片


无意中看到 telephone-line 有一种渐变颜色的效果,看起来很棒,但telephone-line的源码有些难懂,所以自己动手实现类似的效果

渐变颜色

渐变颜色的实现可使用color-gradient

1(color-gradient
2 '(0 0 0)
3 (color-name-to-rgb "red") 10)

实现原理是对红(R)、绿(G)、蓝(B)三个颜色通道分别取 n + 2 个过渡值,n 为中间颜色过渡状态,所以对于red#000#a0a0a0等颜色需要转化为RGB色彩模式

生成XPM图片

XPM图片格式参考 https://en.wikipedia.org/wiki/X_PixMap(XPM3)

大概是这样的

 1/* XPM */
 2static char * XFACE[] = {
 3/* <Values> */
 4/* <width/columns> <height/rows> <colors> <chars per pixel>*/
 5"48 4 2 1",
 6/* <Colors> */
 7"a c #ffffff",
 8"b c #000000",
 9/* <Pixels> */
10"abaabaababaaabaabababaabaabaababaabaaababaabaaab",
11"abaabaababaaabaabababaabaabaababaabaaababaabaaab",
12"abaabaababaaabaabababaabaabaababaabaaababaabaaab",
13"abaabaababaaabaabababaabaabaababaabaaababaabaaab"
14};

渐变颜色XPM图片原理就是使用不同的字符代表不同状态的渐变颜色,当所使用的字符数越多,渐变效果越好,但同时XPM图片的宽度也就越大

  • 生成不同字符

    1;; 0~9
    2(mapcar 'number-to-string (number-sequence 0 9))
    3;; a~z
    4(mapcar 'char-to-string (number-sequence ?a ?z))
  • 不同字符对应不同颜色

    1(let ((number -1))
    2  (mapconcat
    3   (lambda(x)
    4     (setq number (+ number 1))
    5     (format "\"%s c %s\"," (nth number maple-xpm-chars) (apply 'color-rgb-to-hex x)))
    6   (color-gradient
    7    (color-name-to-rgb color1)
    8    (color-name-to-rgb color2) width) ""))

效果显示

完整代码及更多XPM图片

作者: honmaple
链接: https://honmaple.me/articles/2019/07/elisp生成渐变XPM图片.html
版权: CC BY-NC-SA 4.0 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
wechat
alipay

加载评论