Я пытаюсь настроить пользовательские скриншоты полутонов на угол / частоту с помощью 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) следующие паттерны в прогрессии от белого к (почти) черному:
Откуда приходят эти точки и как их избежать? Я заметил, что точки внутри белого цвета пропали на 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 низкого дизеринга, чтобы сделать проблему более заметной, но даже в настройках по умолчанию точки есть.