Solía dirigir un estudio de serigrafía (era bastante pequeño), y aunque nunca he hecho la impresión de separación de colores, estoy razonablemente familiarizado con los principios. Así es como yo lo enfoque:
- dividir la imagen en C, M, Y, K.
- Girar cada imagen separados por 0, 15, 30, y 45 grados, respectivamente.
- Tome el medio tono de cada imagen (el tamaño del punto será proporcional a la intensidad).
- Gire hacia atrás cada imagen de medio tono.
Ahora tiene sus imágenes separadas por color. Como mencionas, el paso de rotación reduce los problemas de alineación de puntos (lo que ensuciaría todo) y cosas como Moiré pattern effects se minimizarán razonablemente.
Esto debería ser bastante fácil de codificar usando PIL.
Actualización 2:
escribí algo de código rápida que va a hacer esto para usted, sino que también incluye una función GCA
(descrito a continuación):
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()
Esto a su vez esto:
en esto (desdibuja los ojos y aléjate de la moni tor):
Nota que el muestreo de imagen puede ser píxel por píxel (preservando así la resolución de la imagen original, en la imagen final). Para ello, establezca sample=1
, en cuyo caso debe establecer scale
en un número mayor para que haya varios tamaños de puntos posibles. Esto también dará como resultado un tamaño de imagen de salida más grande (tamaño de imagen original * escala ** 2, ¡así que tenga cuidado!).
De forma predeterminada, al convertir de RGB
a CMYK
, el canal K
(el canal negro) está vacío. Si necesita el canal K
o no, depende de su proceso de impresión. Hay varias razones posibles por las que podría desearlo: obtener un negro mejor que la superposición de CMY
, ahorrar tinta, mejorar el tiempo de secado, reducir el sangrado de tinta, etc. De todos modos, también escribí una pequeña función Grey component replacement , para que pueda configurar el porcentaje del canal K
con el que desea reemplazar CMY
se superponen (lo explico un poco más en los comentarios del código).
Aquí hay un par de ejemplos para ilustrar. Procesando el letter F
de la imagen, con sample=1
y scale=8
, con una resolución bastante alta.
Los 4 CMYK
canales, con percentage=0
, tan vacío K
de canal:
se combina para producir:
CMYK
canales, con percentage=100
, por lo K
canal es usado. Se puede ver el canal cian está totalmente suprimida, y los canales de magenta y amarillo usar mucha menos tinta, en la banda de negro en la parte inferior de la imagen:
actualicé mi código, espero que sea útil;) – fraxel
Ahora vinculado: [¿Cómo semitono una imagen en blanco y negro?] (Https://stackoverflow.com/questions/47828014/how-to-halftone-a-black- and-white-picture) – martineau