Avevo uno studio di serigrafia (era piuttosto piccolo) e, anche se non ho mai realizzato la stampa a colori, ho una certa familiarità con i principi. Questo è come mi avvicinarlo:
- dividere l'immagine in C, M, Y, K.
- Ruota ciascuna immagine separato da 0, 15, 30, e 45 gradi rispettivamente.
- Prendere il semitono di ogni immagine (la dimensione del punto sarà proporzionale all'intensità).
- Ruota indietro di ciascuna immagine mezzatinta.
Ora hai le tue immagini a colori separati. Come si menziona, la fase di rotazione riduce i problemi di allineamento dei punti (che potrebbero rovinare tutto) e cose come Moiré pattern effects saranno ragionevolmente ridotte al minimo.
Questo dovrebbe essere piuttosto facile da codificare utilizzando PIL.
Aggiornamento 2:
ho scritto un codice rapido che lo farà per voi, ma include anche una funzione GCA
(descritto di seguito):
import Image, ImageDraw, ImageStat
def gcr(im, percentage):
'''basic "Gray Component Replacement" function. Returns a CMYK image with
percentage gray component removed from the CMY channels and put in the
K channel, ie. for percentage=100, (41, 100, 255, 0) >> (0, 59, 214, 41)'''
cmyk_im = im.convert('CMYK')
if not percentage:
return cmyk_im
cmyk_im = cmyk_im.split()
cmyk = []
for i in xrange(4):
cmyk.append(cmyk_im[i].load())
for x in xrange(im.size[0]):
for y in xrange(im.size[1]):
gray = min(cmyk[0][x,y], cmyk[1][x,y], cmyk[2][x,y]) * percentage/100
for i in xrange(3):
cmyk[i][x,y] = cmyk[i][x,y] - gray
cmyk[3][x,y] = gray
return Image.merge('CMYK', cmyk_im)
def halftone(im, cmyk, sample, scale):
'''Returns list of half-tone images for cmyk image. sample (pixels),
determines the sample box size from the original image. The maximum
output dot diameter is given by sample * scale (which is also the number
of possible dot sizes). So sample=1 will presevere the original image
resolution, but scale must be >1 to allow variation in dot size.'''
cmyk = cmyk.split()
dots = []
angle = 0
for channel in cmyk:
channel = channel.rotate(angle, expand=1)
size = channel.size[0]*scale, channel.size[1]*scale
half_tone = Image.new('L', size)
draw = ImageDraw.Draw(half_tone)
for x in xrange(0, channel.size[0], sample):
for y in xrange(0, channel.size[1], sample):
box = channel.crop((x, y, x + sample, y + sample))
stat = ImageStat.Stat(box)
diameter = (stat.mean[0]/255)**0.5
edge = 0.5*(1-diameter)
x_pos, y_pos = (x+edge)*scale, (y+edge)*scale
box_edge = sample*diameter*scale
draw.ellipse((x_pos, y_pos, x_pos + box_edge, y_pos + box_edge), fill=255)
half_tone = half_tone.rotate(-angle, expand=1)
width_half, height_half = half_tone.size
xx=(width_half-im.size[0]*scale)/2
yy=(height_half-im.size[1]*scale)/2
half_tone = half_tone.crop((xx, yy, xx + im.size[0]*scale, yy + im.size[1]*scale))
dots.append(half_tone)
angle += 15
return dots
im = Image.open("1_tree.jpg")
cmyk = gcr(im, 0)
dots = halftone(im, cmyk, 10, 1)
im.show()
new = Image.merge('CMYK', dots)
new.show()
Questo si trasformerà questo:
in questo (offuscare gli occhi e allontanarsi dal moni tor):
noti che il campionamento dell'immagine può essere pixel per pixel (preservando così la risoluzione dell'immagine originale, nell'immagine finale). A tale scopo, impostare sample=1
, nel qual caso è necessario impostare scale
su un numero maggiore in modo che vi siano un numero di dimensioni di punti possibili. Ciò determinerà anche una dimensione dell'immagine in uscita più grande (dimensione dell'immagine originale * scala ** 2, quindi attenzione!).
Per impostazione predefinita quando si converte da RGB
a CMYK
il canale K
(canale nero) è vuoto. Se hai bisogno del canale K
o meno dipende dal tuo processo di stampa. Ci sono varie possibili ragioni per cui potresti volerlo: ottenere un nero migliore rispetto alla sovrapposizione di CMY
, risparmiando inchiostro, migliorando il tempo di asciugatura, riducendo il margine di inchiostro, ecc. Comunque ho anche scritto un po 'la funzione Grey component replacementGCA
, così puoi impostare percentuale del canale K
che si desidera sostituire con lo CMY
(si spiego un po 'oltre nei commenti del codice).
Ecco un paio di esempi da illustrare. Elaborazione di letter F
dall'immagine, con sample=1
e scale=8
, quindi con una risoluzione piuttosto elevata.
I 4 CMYK
canali, con percentage=0
, così vuoto K
channel:
combina per produrre:
CMYK
canali, con percentage=100
, così K
canale utilizzato. È possibile vedere il canale ciano è completamente soppressa, ei canali magenta e giallo usare un inchiostro molto meno, nella banda nera nella parte inferiore dell'immagine:
aggiornato il mio codice, spero che sia utile;) – fraxel
Ora collegato: [Come retinatura a mezzitoni di un'immagine in bianco e nero?] (Https://stackoverflow.com/questions/47828014/how-to-halftone-a-black- e-white-picture) – martineau