后记:绘制渐变

Posted

技术标签:

【中文标题】后记:绘制渐变【英文标题】:Postscript: Drawing a Gradient 【发布时间】:2011-09-21 13:00:19 【问题描述】:

我正在学习 Postscript 我正在尝试创建一种方法来绘制垂直渐变

这是我的代码:

%!PS-Adobe-3.0

%%%%%%%%%%%%%%%%%%%%%%%
% draw a RECTANGLE
/Rect 
/h exch def % height
/w exch def % width
w 0 rlineto
0 h rlineto
-1.0 w mul  0 rlineto
0 -1.0 h mul rlineto
 def
%%%%%%%%%%%%%%%%%%%%%%%
% draw a Gradient
/VGrad 
/h exch def % height
/w exch def % width
/c2 exch def %gray-end
/c1 exch def %gray-start
/index 0.0  def %loop-index

0 1 h  %loop over height
    gsave
    c2 c1 sub  index h div mul c1 add setgray

    w h index sub Rect
    stroke

    /index index 1.0 add def % index++
    grestore
     for

 def
%%%%%%%%%%%%%%%%%%%%%%%
%test script
200 600 moveto
.1 .9 100 10 VGrad

showpage

但是 GS 报错:

GPL Ghostscript 8.70 (2009-07-31)
Copyright (C) 2009 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Error: /undefinedresult in --div--
Operand stack:
   0   1   2   3   4   5   0.8   5.0   0.0
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1862   1   3   %oparray_pop   1861   1   3   %oparray_pop   1845   1   3   %oparray_pop   1739   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   6   1   10   --nostringval--   %for_pos_int_continue   --nostringval--
Dictionary stack:
   --dict:1150/1684(ro)(G)--   --dict:0/20(G)--   --dict:75/200(L)--
Current allocation mode is local
Current file position is 588
GPL Ghostscript GPL Ghostscript 8.708.70: : Unrecoverable error, exit code 1
Unrecoverable error, exit code 1

我哪里错了?

【问题讨论】:

顺便说一句,除非您使用 DSC cmets,否则魔术线应该是 %!PS 甚至只是 %!-Adobe-3.0 部分是文件打算符合的 DSC 版本号。 【参考方案1】:

通过使用巧妙的堆栈操作和 CTM 效果,您的程序将执行得更快。

这不像你的那样平滑渐变,但执行得更快,并且函数被计算为单行语句(我只是 更喜欢,无法解释为什么)。

此外,发布使用情况和示例页面也很不错(当您不需要它时很容易修剪,但当您确实需要它时......??!!)无论如何,这是你重写的程序我的方式,FWIW。

正如我所说,输出在当前形式下并不那么漂亮。但是您可以通过使用currenttransfersettransfer 更改灰度传递函数和/或将框的计算更改为对数缩放,更改灰度的范围和速度来修改渐变。在“更紧密”的代码中应该更容易看到这些东西。堆栈 cmets 可帮助您在每行末尾“检查您的理解”。

编辑:我无法停止玩它!我已经分解了循环并梳理了更多参数。

编辑:又一个扩展。一张漂亮的照片怎么样?

%!

/box  % x y w h
    4 2 roll moveto % w h
    1 index 0 rlineto % w h
    0 exch rlineto % w
    neg 0 rlineto %
    closepath
 def

/poly  % n
    0.5 0 moveto
     ? rotate 0.5 0 lineto  % n proc
    dup 0 360 4 index div put % n 360/n...
    repeat
    closepath
 def

% num-slices shapeproc matrix grayproc  agrad  -
% repeatedly (fill shape, concat matrix, transform currentgray)
/agrad 
    3 dict begin /gray exch def /mat exch def /shape exch def
    ( //shape exec //mat concat currentgray //gray exec setgray )
    token pop exch pop end bind repeat
 def

/shapes [
     -0.5 -0.5 1 1 box fill    %box shape
     0 0 0.5 0 360 arc fill    %circle shape
     0 0 0.5 0 180 arc fill    %fan shape
     5 poly fill  %pentagon
     6 poly fill  %hexagon
    ] def

/mats [
    1 index 2 exch div 1 exch sub   dup matrix scale  %pyramid matrix
    1 index 2 exch div 1 exch sub   1 matrix scale  %horizontal matrix
    1 index 2 exch div 1 exch sub   1 exch matrix scale  %vertical matrix
    ] def

% mat-no shape-no gray0 grayF n x y w h  dograd  -
/dograd 
    gsave
        4 2 roll translate % m sh g0 gF n w h
        scale % m sh g0 gF n
        3 1 roll % m sh n g0 gF
        1 index sub 2 index div % m sh n g0 (gF-g0)/n
        [ exch /add cvx ] cvx % m sh n g0 grayproc
        3 1 roll setgray % m sh grayproc n
        3 -1 roll shapes exch get % m gray n shape
        4 -1 roll mats exch get exec % gray n shape mat
        4 -1 roll %n shape matrix gray
        agrad
    grestore
 def

%mat shape g0 gF n x y w h
0 4 .7 .1 20 300 400 600 800 dograd

0 0 0 1 10 100 650 200 200 dograd
1 1 0 1 20 300 650 200 200 dograd
2 2 .5 1 30 500 650 200 200 dograd

0 3 1 0 40 100 400 200 200 dograd
1 4 1 .5 50 300 400 200 200 dograd
2 1 .5 0 60 500 400 200 200 dograd

0 2 .1 .9 10 100 150 200 200 dograd
1 3 .2 .8 20 300 150 200 200 dograd
2 4 .3 .7 30 500 150 200 200 dograd

showpage

【讨论】:

我已经破解了一些spiral gradients。图片很漂亮,但代码有点乱。 尽管早期的过程ygrad 没有在这张图片中使用,但是阅读它对于希望理解后面的过程的后记程序员来说是非常有帮助的。不要自吹自擂,但这不是初学者级别的后记。它在将程序主体提供给循环操作符之前动态修改它们以获得最大速度。这种速度使我们有机会做......嗯..老鼠我从来没有用“未优化”代码衡量过这个。所有这些喧嚣可能完全没有必要。 :)【参考方案2】:

好的,我发现了问题:index似乎是保留字。这是一个功能版本:

/box

4 dict begin
/height exch def
/width exch def
/y exch def
/x exch def
x y moveto
width 0 rlineto
0 height rlineto
width -1 mul 0 rlineto
0 height -1 mul rlineto
end
 bind def


/gradient

4 dict begin
/height exch def
/width exch def
/y exch def
/x exch def
/i 0 def
height 2 div /i exch def

0 1 height 2 div 
    1 i height 2.0 div div sub setgray
    newpath
    x  
    y height 2 div i sub  add
    width
    i 2 mul
    box
    closepath
    fill
    i 1 sub /i exch def
    for
newpath
0 setgray
0.4 setlinewidth
x y width height box
closepath
stroke
end
 bind def

【讨论】:

【参考方案3】:

我没有尝试完全理解您的代码。但是错误消息试图告诉您您正在除以零(查看剩余操作数堆栈的顶部元素:“0”)。

只需将“1”添加到您的h 变量(在h 之后插入1 add)即可让您的 PostScript 程序通过 Ghostscript 解释器运行并让它绘制一些东西(尽管这可能看起来不像您想象的那样...... ..)。

【讨论】:

以上是关于后记:绘制渐变的主要内容,如果未能解决你的问题,请参考以下文章

iOS 绘制颜色渐变圆环 --- 值得一看

「AI教程」轻松绘制扇形渐变

在屏幕上绘制渐变

无绘制圆形渐变

如何在 PHP 中绘制渐变矩形? [关闭]

UIBezierPath下绘制渐变