Skip to content

Commit a66f97e

Browse files
committed
GCR added
In CMYK we need to use GCR for black channel for 4 channel printers It optimized based on our requirement
1 parent 500affb commit a66f97e

File tree

1 file changed

+82
-78
lines changed

1 file changed

+82
-78
lines changed

halftone.py

Lines changed: 82 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,106 @@
1-
# %% libraries
21
import PIL.Image as Image
32
import numpy.matlib
43
import numpy as np
54
import random
65
import math
6+
import matplotlib.pyplot as plt
7+
import matplotlib.image as mpimg
78

8-
# %% functions
9-
dithMat = [
10-
# 8x8 sprial
11-
[[62, 58, 45, 41, 37, 49, 53, 61],
12-
[54, 34, 25, 21, 17, 29, 33, 57],
13-
[50, 30, 13, 9, 5, 12, 24, 44],
14-
[38, 18, 6, 1, 0, 8, 20, 40],
15-
[42, 22, 10, 2, 3, 4, 16, 36],
16-
[46, 26, 14, 7, 11, 15, 28, 48],
17-
[59, 35, 31, 19, 23, 27, 32, 52],
18-
[63, 55, 51, 39, 43, 47, 56, 60]],
9+
dithMat =[
1910
# 8x8 dispresed
20-
[[1, 30, 8, 28, 2, 29, 7, 27],
21-
[17, 9, 24, 16, 18, 10, 23, 15],
22-
[5, 25, 3, 32, 6, 26, 4, 31],
23-
[21, 13, 19, 11, 22, 14, 20, 12],
24-
[2, 29, 7, 27, 1, 30, 8, 28],
25-
[18, 10, 23, 15, 17, 9, 24, 16],
26-
[6, 26, 4, 31, 5, 25, 3, 32],
27-
[22, 14, 20, 12, 21, 13, 19, 11]],
28-
# 8X8 octa_dot
29-
[[45, 17, 25, 37, 47, 19, 27, 39],
30-
[49, 1, 9, 57, 51, 3, 11, 59],
31-
[29, 33, 41, 21, 31, 35, 43, 23],
32-
[13, 61, 53, 5, 15, 63, 55, 7],
33-
[48, 20, 28, 40, 46, 18, 26, 38],
34-
[52, 4, 12, 60, 50, 2, 10, 58],
35-
[32, 36, 44, 24, 30, 34, 42, 22],
36-
[16, 64, 56, 8, 14, 62, 54, 6]],
37-
# 5x5 diamond
38-
[[5, 118, 160, 58, 17],
39-
[48, 201, 232, 170, 99],
40-
[129, 211, 252, 242, 150],
41-
[89, 191, 221, 181, 68],
42-
[38, 78, 140, 108, 27]],
11+
[[ 1, 30, 8, 28, 2, 29, 7, 27],
12+
[ 17, 9, 24, 16, 18, 10, 23, 15],
13+
[ 5, 25, 3, 32, 6, 26, 4, 31],
14+
[ 21, 13, 19, 11, 22, 14, 20, 12],
15+
[ 2, 29, 7, 27, 1, 30, 8, 28],
16+
[ 18, 10, 23, 15, 17, 9, 24, 16],
17+
[ 6, 26, 4, 31, 5, 25, 3, 32],
18+
[ 22, 14, 20, 12, 21, 13, 19, 11]],
4319
# 5x5 clockwise sprial
4420
[[3, 10, 16, 11, 4],
45-
[9, 20, 21, 17, 12],
46-
[15, 24, 25, 22, 13],
47-
[8, 19, 23, 18, 5],
48-
[2, 7, 14, 6, 1]],
49-
# 4x4 ordered
50-
[[5, 9, 6, 10],
51-
[13, 1, 14, 2],
52-
[7, 11, 4, 8],
53-
[15, 3, 12, 0]],
21+
[ 9, 20, 21, 17, 12],
22+
[ 15, 24, 25, 22, 13],
23+
[ 8, 19, 23, 18, 5],
24+
[ 2, 7, 14, 6, 1]],
25+
26+
[[0, 8, 2, 10],
27+
[12, 4, 14, 6],
28+
[3, 11, 1, 9],
29+
[15, 7, 13, 5]],
30+
31+
[[0, 32, 8, 40, 2, 34, 10, 42],
32+
[48, 16, 56, 24, 50, 18, 58, 26],
33+
[3, 35, 11, 43, 1, 33, 9, 41],
34+
[51, 19, 59, 27, 49, 17, 57, 25]]
5435
]
5536

37+
def gcr(im):
38+
cmyk_im = im.convert('CMYK')
39+
cmyk_im = cmyk_im.split()
40+
cmyk = []
41+
check_brightness = []
42+
for i in range(4):
43+
cmyk.append(np.asarray(cmyk_im[i]))
44+
check_brightness.append(np.mean(cmyk[i]) > 128)
45+
cmyk = np.asarray(cmyk)
46+
check_brightness = np.asarray(check_brightness)
47+
if np.mean(check_brightness) > 0.5:
48+
percentage = round(random.uniform(0.1,0.5),1)
49+
else:
50+
percentage = round(random.uniform(0.5,0.9),1)
51+
52+
for x in range(im.size[0]):
53+
for y in range(im.size[1]):
54+
gray = min(cmyk[0][x,y], cmyk[1][x,y], cmyk[2][x,y])* (100/100)
55+
for i in range(3):
56+
cmyk[i][x,y] = cmyk[i][x,y] - gray
57+
cmyk[3][x,y] = gray
58+
cmyk_final = []
59+
for i in range(4):
60+
cmyk_final.append(Image.fromarray(cmyk[i]).convert('L'))
61+
return Image.merge('CMYK', cmyk_final)
5662

57-
def get_resDmat(channel_size, dithMat):
58-
newSzY, newSzX = channel_size[1], channel_size[0]
63+
def get_resDmat(channel_size,dithMat):
64+
newSzY,newSzX = channel_size[1],channel_size[0]
5965
minDmat = min(min(dithMat))
6066
maxDmat = max(max(dithMat))
61-
nbOfIntervals = maxDmat - minDmat + 2
62-
singleInterval = 255 / nbOfIntervals
63-
scaledDithMat = np.multiply(np.subtract(dithMat, minDmat + 1), singleInterval)
67+
nbOfIntervals = maxDmat-minDmat+2
68+
singleInterval = 255/nbOfIntervals
69+
scaledDithMat = np.multiply(np.subtract(dithMat , minDmat+1),singleInterval)
6470
scaledDithMat = scaledDithMat.astype(int)
6571

66-
dmatSzY, dmatSzX = len(scaledDithMat), len(scaledDithMat[0])
67-
nX = math.ceil(newSzX / dmatSzX)
72+
73+
dmatSzY, dmatSzX = len(scaledDithMat),len(scaledDithMat[0])
74+
nX = math.ceil(newSzX / dmatSzX)
6875
nY = math.ceil(newSzY / dmatSzY)
69-
resDmat = np.matlib.repmat(scaledDithMat.astype(int), nY, nX)[:newSzY, :newSzX]
76+
resDmat = np.matlib.repmat(scaledDithMat.astype(int), nY, nX)[:newSzY,:newSzX]
7077
return resDmat
7178

72-
73-
def generate_halftone(im):
74-
cmyk_im = im.convert('CMYK')
75-
dithMat_sample = dithMat[random.randint(0, len(dithMat) - 1)]
79+
def generate_halftone(im,):
80+
cmyk_im = gcr(img)
81+
dithMat_sample = dithMat[random.randint(0,3)]
7682
cmyk = cmyk_im.split()
77-
angles = [[15, 45, 0, 75],
83+
angles = [[75,15,0,45],
7884
[45, 15, 0, 75],
79-
[0, 0, 0, 0]]
80-
81-
angles = angles[random.randint(0, len(angles) - 1)]
82-
if cmyk[0] == cmyk[1] == cmyk[2]:
83-
angles = angles[:1] * 4
85+
[75,45,0,15]]
86+
87+
angles = angles[random.randint(0,2)]
88+
if cmyk[0] == cmyk[1] == cmyk[2] :
89+
angles = angles[:1]*4
8490
dots = []
85-
for x, i in enumerate(cmyk):
91+
for x,i in enumerate(cmyk):
8692
channel_Rotation = i.rotate(angles[x], expand=1)
87-
channel = np.asarray(channel_Rotation) > get_resDmat(channel_Rotation.size, dithMat_sample)
88-
channel = Image.fromarray(channel * 255).convert('L').rotate(-angles[x], expand=1)
89-
w, h = channel.size
90-
im_x, im_y = i.size
91-
x1 = (w - im_x) / 2
92-
y1 = (h - im_y) / 2
93-
channel = channel.crop((x1, y1, x1 + im_x, y1 + im_y))
93+
#print(channel_Rotation.size)
94+
channel = np.asarray(channel_Rotation) > get_resDmat(channel_Rotation.size,dithMat_sample)
95+
channel = Image.fromarray(channel * 255).convert('L').rotate(-angles[x],expand=1)
96+
#channel = channel.rotate(-angles[x],expand=1)
97+
w,h = channel.size
98+
im_x,im_y = i.size
99+
x1 = (w-im_x)/2
100+
y1 = (h-im_y)/2
101+
channel = channel.crop((x1, y1, x1+im_x, y1+im_y))
94102
dots.append(channel)
95-
96-
halftoned_im = Image.merge('CMYK', dots)
97-
return halftoned_im.convert('RGB')
98-
99-
# %% test
100-
# im = Image.open('data/Places365_val_00000001.jpg')
101-
# imh = generate_halftone(im)
102-
# imh.show()
103+
104+
halftoned_im = Image.merge('CMYK',dots)
105+
106+
return halftoned_im.convert('RGB')

0 commit comments

Comments
 (0)