半色调图像在Python(Halftone Images In Python)

2019-06-24 09:20发布

我的工作要求我每个颜色分离出的CYMK图像,并生成将一个特殊的半色调打印机上打印半色调图像的项目。 所用的方法是类似物丝印在该过程几乎是相同的。 拍摄一张照片,打破了每个颜色通道。 于是产生了半色调的画面。 每个彩色屏幕必须有它的屏幕15-45(可调)度倾斜。 点大小和LPI必须从用户可配置的值来计算,以达到不同的效果。 我这个过程我告诉在丝印使用,但我一直无法找到解释CYMK半色调的任何信息。 我发现很多减少到一个单一的颜色,并产生新的打印样式的B / W半色调图像。

我猜想,我需要:1.将文件拆分成它的颜色通道。 2.生成用于该通道的单色半色调图像。 3.度*信道数目的数目歪斜所得半色调图像。 有谁知道,如果这是正确的做法?

有谁知道这方面的任何现有的Python代码? 或者有什么好解释这一过程或算法的?

Answer 1:

我用来运行丝网印刷工作室(这是一个相当小的一个),虽然我从来没有做过真正分色印刷,我相当熟悉的原则。 这是我会怎么来解决:

  1. 分割图像转换成C,M,Y,K。
  2. 由0,15,30旋转每个分离的图像,和分别为45度。
  3. 取各图像的半色调(点尺寸将正比于强度)。
  4. 旋转回每个半色调图像。

现在,你有你的颜色分离的图像。 至于你提到的,旋转步骤减少点对齐问题(这混乱的一切行动),和喜欢的东西莫尔条纹的效果将相当最小化。

这应该是很容易使用的代码PIL 。

更新2:

我写了一些简单的代码,会为你做到这一点,它也包括一个GCA功能(如下所述):

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()

这会变成这样:

到这个(模糊你的眼睛,从显示器移开):

注意,图像采样可以是逐个像素(从而保持原始图像的分辨率,在最终图像中)。 通过设置这样做sample=1 ,在这种情况下,你需要设置scale为更大的数字,这样有一些可能的点尺寸。 这也将导致较大的输出图像的大小(原始图像尺寸* **规模2,因此要当心!)。

默认情况下,当您从转换RGBCMYKK通道(黑色通道)是空的。 无论您需要的K通道与否取决于你的印刷工艺。 有您可能希望它各种可能的原因:得到一个更好的比黑色的重叠CMY ,节省油墨,改善干燥时间,降低油墨流血,等等。总之我也写了一个小灰成分替代功能GCA ,这样你就可以设定的百分比K要替换通道CMY具有重叠(我在代码中的注释解释远一点)。

下面是几个例子来说明。 处理所述letter F从图像,与sample=1scale=8 ,所以相当高的分辨率。

4 CMYK通道, percentage=0 ,所以空K信道:

结合产生:

CMYK通道, percentage=100 ,所以K信道被使用。 你可以看到青色通道被完全supressed,和品红色和黄色的信道在图像的底部使用较少的大量墨水,在黑色带:



Answer 2:

我的解决方案还使用PIL,而是依赖于内部支持内部抖动法(弗洛伊德斯坦伯格)。 创建文物,虽然,所以我正在考虑重写它的C代码。

    from PIL import Image

    im  = Image.open('tree.jpg')             # open RGB image
    cmyk= im.convert('CMYK').split()         # RGB contone RGB to CMYK contone
    c = cmyk[0].convert('1').convert('L')    # and then halftone ('1') each plane
    m = cmyk[1].convert('1').convert('L')    # ...and back to ('L') mode
    y = cmyk[2].convert('1').convert('L')
    k = cmyk[3].convert('1').convert('L')

    new_cmyk = Image.merge('CMYK',[c,m,y,k]) # put together all 4 planes
    new_cmyk.save('tree-cmyk.jpg')           # and save to file

隐式GCR PIL应用也可以用一个更通用的一个扩展,但我试图描述一个简单的解决方案,其中也分辨率和采样将被忽略。



文章来源: Halftone Images In Python