-
Notifications
You must be signed in to change notification settings - Fork 1
/
LUT.py
186 lines (159 loc) · 6 KB
/
LUT.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
##################################################################
# R E A D M E
##################################################################
'''
Methods to launch this script:
- from command line
- three main parameters: -i, -o, -l
-i specifies the input file
- if -i is not used, all files in the current directory and all subdirectories (except _LUTs and _OUTPUT folders) will be used
-o specifies where to output
- if -o is not used, the output file path will automatically be the same as the input, under the _OUTPUT folder
-l specifies the LUT used (from _LUTs folder)
- if -l is not used, lut-day.png is used
version 1.0
2019-11-08
'''
import argparse
import sys
import os
import math
from PIL import Image
def load_lut(lut_filename):
global lut_3d
lut_3d = {}
# read the LUT image
if os.path.isfile(lut_filename) == False:
lut_path = os.path.join('_LUTs', lut_filename)
lut = Image.open(lut_path)
else:
lut = Image.open(lut_filename)
# populate the LUT dictionary
n = 0
for y in range(0, lut.height):
for x in range(0, lut.width):
x_local = x%16
z = math.floor(x/16)
coord = (x_local, y, z)
lut_3d[str(coord)] = lut.getpixel( (x, y) )
#print(x,y,':',lut.getpixel((x,y)))
n+=1
# print the LUT dictionary (debug)
'''
i = 0
for t in lut_3d.items():
zz = math.floor(i/(16*16))
print(zz, i, t)
i+=1
'''
def lerp_color(color1, color2, factor):
output_R = color1[0] + ( (color2[0] - color1[0]) * factor)
output_G = color1[1] + ( (color2[1] - color1[1]) * factor)
output_B = color1[2] + ( (color2[2] - color1[2]) * factor)
return (output_R, output_G, output_B)
def lerp_plane(r_min, r_max, g_min, g_max, b, input):
i00 = (r_min, g_min, b)
i01 = (r_max, g_min, b)
i10 = (r_min, g_max, b)
i11 = (r_max, g_max, b)
lut00 = lut_3d[str(i00)]
lut01 = lut_3d[str(i01)]
lut10 = lut_3d[str(i10)]
lut11 = lut_3d[str(i11)]
R_interpolate = ( input[0] - (r_min*17) )/17
G_interpolate = ( input[1] - (g_min*17) )/17
c0 = lerp_color(lut00, lut01, R_interpolate)
c1 = lerp_color(lut10, lut11, R_interpolate)
return lerp_color(c0, c1, G_interpolate)
def process_image(input_image_path, output_image_path):
input_img = Image.open(input_image_path)
output_img = Image.new('RGBA', (input_img.width, input_img.height), color = (0,0,0,0))
for y in range(0, input_img.height):
for x in range(0, input_img.width):
# get RGB of pixel
if input_img.mode != 'RGBA':
input_img = input_img.convert('RGBA')
input_pix = input_img.getpixel( (x, y) )
input_R = input_pix[0]
input_G = input_pix[1]
input_B = input_pix[2]
alpha = input_pix[3]
if alpha != 0:
# find cage
cage_R_min = math.floor( input_R/17 )
cage_R_max = math.ceil( input_R/17 )
cage_G_min = math.floor( input_G/17 )
cage_G_max = math.ceil( input_G/17 )
cage_B_min = math.floor( input_B/17 )
cage_B_max = math.ceil( input_B/17 )
B_interpolate = ( input_B - (cage_B_min*17) )/17
plane0 = lerp_plane(cage_R_min, cage_R_max, cage_G_min, cage_G_max, cage_B_min, input_pix)
plane1 = lerp_plane(cage_R_min, cage_R_max, cage_G_min, cage_G_max, cage_B_max, input_pix)
output = lerp_color(plane0, plane1, B_interpolate)
output_RGBA = ( int(output[0]), int(output[1]), int(output[2]), alpha)
# put pixel in output image
output_img.putpixel( (x,y) , output_RGBA)
# save output image
output_folder = os.path.dirname(output_image_path)
os.makedirs(output_folder, exist_ok = True)
output_img.save(output_image_path)
print('Saved', output_image_path)
def run(options):
lut_filename = options['lut']
load_lut(lut_filename)
if options['input'] != '':
input_filename = options['input']
output_filename = options['output']
if options['output'] == '':
output_filename = os.path.join('_OUTPUT', input_filename)
process_image(input_filename, output_filename)
else:
# walk through the directory and process all PNG files
current_script_path = os.path.realpath(__file__)
current_script_directory = os.path.dirname(current_script_path)
print('script_directory:', current_script_directory)
walked_instruction_list = []
for root, dirs, files in os.walk(current_script_directory):
for f in files:
if '_LUTs' not in root:
if '_OUTPUT' not in root:
if f[-4:].lower() == '.png':
walked_instruction_list.append( os.path.join(root, f) )
for i in walked_instruction_list:
input_path = i
relative_input_path_i = i
relative_input_path = relative_input_path_i.replace(current_script_directory, '')[1:]
relative_output_path = os.path.join('_OUTPUT', relative_input_path)
process_image(input_path, relative_output_path)
print('Walked instructions detected:\n', walked_instruction_list)
if __name__ == '__main__':
if len(sys.argv) > 2:
parser = argparse.ArgumentParser(description = 'Process some arguments.')
parser.add_argument('-i','--input',
help='File to process.'
)
parser.add_argument('-o','--output',
help='File to output.'
)
parser.add_argument('-l','--lut',
help='Override which LUT file to use.'
)
options = vars(parser.parse_args())
default_values = [
('input', ''),
('output', ''),
('lut', 'lut-day.png')
]
for name, def_value in default_values:
if not options[name]:
options[name] = def_value
else:
input_var = ''
if len(sys.argv) > 1:
input_var = sys.argv[1]
options = {
'input' : input_var,
'output': '',
'lut' : 'lut-day.png'
}
run(options)