Избегайте точек в пустых местах с помощью пользовательских полутоновых экранных наборов - PullRequest
1 голос
/ 07 ноября 2019

Я пытаюсь настроить пользовательские скриншоты полутонов на угол / частоту с помощью ghostscript и столкнулся со специфической проблемой. Результирующий вывод содержит черные точки там, где их не должно быть.

В качестве средства воспроизведения я нашел этот код :

%!PS-Adobe-2.0
% Sample code to explore the different screen and spot functions
% Written by Bruce Barnett 
% Inspired by Michael Thorne
% PostScript Language Journal Vol 1, Number 4
%
%

% define some abbreviations

/l /lineto load def
/m /moveto load def
/rl /rlineto load def
/rm /rmoveto load def
/sg /setgray load def
/sh /show load def
/slw /setlinewidth load def
/st /stroke load def
/tr /translate load def

% and some places to store some information
/str 300 string def % define a string
/ss 50 def     % defines square size
/fountstring 256 string def


% print a fountain
/PrintFountain {
    % create a string containing values from  0 to 255
    0 1 255 {fountstring exch dup put } for
    % scale a 1 by 1 image to the size that will spread across the page
    % first number is the width, second the height
    600 45 scale
    % construct/transform the image
    256 1 8 [256 0 0 1 0 0] {fountstring} image
} bind def


% Print a tinted box
/TintBox { %define a tinted box, size (ss by ss)
    tint 100 div sg
    newpath
    0 0 m
    ss 0 l
    ss ss l
    0 ss l
    closepath fill
} def

/LabelBox {             % define a procedure to label a box
    10 ss 2 div  m      % move to (10, ss/2)

    lettercolor sg      % select color
    tint 3 string cvs sh
    (% grey) sh
} def

/NextLine {-1 ss mul 10 mul  -1 ss mul tr} def % goto next line

/NextLoc {ss 0 tr} def % goto next location (or place for a square)

/PrintMatrix {  % define a procedure to print a row of squares
            % if at the end of the row, go to the next line
            % else - go to the next location
 /tint exch def
 TintBox                % draw the box
 LabelBox               % add the label
 /count count 1 add def     % increase the count by one
 count 11 lt {          % move to next spot
    NextLoc
  } {
    NextLine /count 0 def
  } ifelse
} def

% show details of layout (Halftone, etc.)
/ShowDetails {
    /str 300 string def
    100 750 m
    (Spot Procedure Name= ) show 
    /SpotFunctionName load show     % => freq angle
    currentscreen               % => freq angle proc
    pop                     % ignore procedure
    (     Angle= ) show
    str cvs show                % => freq
    (     Frequency= ) show
    str cvs show
} bind def

% A procedure to set the screen angle
% and remember the name of the function
% so we can print it
/ScreenSet {        % set  screen function
                % ang freq /spot_function ScreenSet
    dup str cvs /SpotFunctionName exch def
    load setscreen
} bind def

/PrintPage {
    % also remember time to print page
    /time_start usertime def
    ShowDetails         % prints the halftone screen
    gsave               % save the graphic state
    ss ss 10 mul tr
    0 0 m
    /count 0 def
    /lettercolor 1 def      % select white letters
    0 1 10 {PrintMatrix} for
    10 1 20 {PrintMatrix} for
    20 1 30 {PrintMatrix} for
    30 1 40 {PrintMatrix} for
    40 1 50 {PrintMatrix} for
    /lettercolor 0 def      % change to black letters
    50 1 60 {PrintMatrix} for
    60 1 70 {PrintMatrix} for
    70 1 80 {PrintMatrix} for
    80 1 90 {PrintMatrix} for
    90 1 100 {PrintMatrix} for
    grestore                %restore graphic state

    gsave                   % save it again, for the fountain
        PrintFountain
    grestore                % restore
    0 sg
    % now print the elapsed time
    100 775 m (elapsed time (milliseconds) = ) show
    usertime time_start sub str cvs show
    showpage            % print the page
} bind def  

% Here are the different spot functions
% These are suggested by Adobe

/spot_round { % simple round
        dup mul exch dup mul add 1 exch sub 
} def


% Inverted Round 
/spot_iround { 
        dup mul exch dup mul add 1 sub 
} def

% Euclidean Composite 
/spot_euclid {  % default on many new PS printers
    abs exch abs 2 copy add 1 gt { 
        1 sub dup mul exch 1 sub dup mul add 1 sub 
    } { 
        dup mul exch dup mul add 1 exch sub 
    } ifelse 
} def

% Rhomboid 
/spot_rhomboid { % Rhomboid
    abs exch abs .8 mul add 2 div 
} def

% Line
/spot_line { 
    exch pop abs 1 exch sub 
} def

% Diamond 
/spot_diamond { 
    abs exch abs 2 copy add .75 le 
        { 
            dup mul exch dup mul add 1 exch sub 
        } { 
            2 copy add 1.25 le { 
                .85 mul add 1 exch sub 
            } { 
                1 sub dup mul exch 1 sub dup mul add 1 sub 
        } ifelse 
    } ifelse 
} def

% Inverted Elliptical
/spot_iellipt { 
    dup mul .9 mul exch dup mul add 1 sub 
} def


/spot_rb { % another from the "Red Book"
    180 mul cos exch 180 mul cos add 2 div
} def

/spot_line { % simple line
    pop
} def

/spot_line2 { % simple line going the other way
    exch pop
} def


% End of definitions, now to print

% Use 8 point Helvetica
8 /Helvetica-Bold findfont exch scalefont setfont 

% each "PrintPage" prints one test page
% Print 5 test pages or different screens
% using the same spot function

53 45       /spot_euclid    ScreenSet PrintPage
75 0        /spot_euclid    ScreenSet PrintPage
83 56       /spot_euclid    ScreenSet PrintPage
106 45  /spot_euclid    ScreenSet PrintPage
150 0       /spot_euclid    ScreenSet PrintPage

% Now print 10 other spot functions, same screen

53 45   /spot_round     ScreenSet PrintPage
53 45   /spot_iround    ScreenSet PrintPage
53 45   /spot_euclid    ScreenSet PrintPage
53 45   /spot_rhomboid  ScreenSet PrintPage
53 45   /spot_line      ScreenSet PrintPage
53 45   /spot_diamond   ScreenSet PrintPage
53 45   /spot_iellipt   ScreenSet PrintPage
53 45   /spot_rb        ScreenSet PrintPage
53 45   /spot_linea     ScreenSet PrintPage
53 45   /spot_lineb     ScreenSet PrintPage

% I think you get the idea.....

% end of file

с gs -r1440 -sOutputFile=test%d.tif -sDEVICE=tiffsep1 -f example1.gs Я получаю test5(black).tif (spot_euclid freq = 150) следующие паттерны в прогрессии от белого к (почти) черному:

white 66% grey 33% grey 3% grey

Откуда приходят эти точки и как их избежать? Я заметил, что точки внутри белого цвета пропали на 720, но для моего приложения мне нужно 1440.

Я уже осмотрелся и нашел людей с похожими проблемами, но без решения. Этот комментарий предполагает, что белый цвет не чистый, но это не объясняет, почему небелые части содержат эти точки.

РЕДАКТИРОВАТЬ: Меньший воспроизводитель

Я заметил, что это поведениетакже можно воспроизвести с помощью меньшего примера и стандартной функции пятна ghostscript:

<< /PageSize [10 10] >> setpagedevice
0.75 0.5 0 0 setcmykcolor
newpath 0 0 moveto 10 0 lineto 10 10 lineto 0 10 lineto closepath fill 
showpage
quit

Запуская это с gs -r300 -dDITHERPPI=20 -sOutputFile=test%d.tif -sDEVICE=tiffsep1 -f test.gs, я получаю следующие выходные значения для каналов CMYK:

Cyan:Magenta:Желтый:Черный:

И для 600 DPI я также получаю точки в пустых каналах:

Cyan:Magenta:Желтый:Черный:

Я использовал PPI низкого дизеринга, чтобы сделать проблему более заметной, но даже в настройках по умолчанию точки есть.

...