happyneishon commited on
Commit
118b48b
·
verified ·
1 Parent(s): 4474e4a

Upload 2 files

Browse files
Files changed (2) hide show
  1. Revision by XpucT.py +566 -112
  2. user.js +49 -35
Revision by XpucT.py CHANGED
@@ -5,11 +5,14 @@ import modules.scripts as scripts
5
  import gradio as gr
6
  import numpy as np
7
  import cv2
 
 
 
8
 
9
- from PIL import Image
10
- from modules.processing import process_images, Processed
11
- from PIL import ImageEnhance, Image, ImageDraw, ImageFilter, ImageChops, ImageOps
12
  from blendmodes.blend import blendLayers, BlendType
 
13
 
14
 
15
  def resetValues(saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider):
@@ -40,124 +43,575 @@ def bestChoiceValues(saturationSlider, temperatureSlider, brightnessSlider, cont
40
  return [saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider]
41
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  class Script(scripts.Script):
44
  def title(self):
45
  return 'Revision'
46
 
 
 
 
47
  def ui(self, is_img2img):
48
- saturationSlider = gr.Slider(0, 2, 1, label='Saturation')
49
- temperatureSlider = gr.Slider(0, 2, 1, label='Temperature')
50
- brightnessSlider = gr.Slider(0, 2, 1, label='Brightness')
51
- contrastSlider = gr.Slider(0, 2, 1, label='Contrast')
52
- sharpnessSlider = gr.Slider(0, 1, 0, label='Sharpness')
53
- blurSlider = gr.Slider(0, 1, 0, label='Blur')
54
- noiseSlider = gr.Slider(0, 1, 0, label='Noise')
55
- vignetteSlider = gr.Slider(0, 1, 0, step=.05, label='Vignette')
56
- exposureOffsetSlider = gr.Slider(
57
- 0, 1, 0, step=.05, label='Exposure offset')
58
- hdrSlider = gr.Slider(0, 1, 0, label='HDR')
59
-
60
- bestChoiceButton = gr.Button(value="Best Choice")
61
- bestChoiceButton.click(bestChoiceValues, inputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider],
62
- outputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider])
63
-
64
- resetSlidersButton = gr.Button(value="Reset Sliders")
65
- resetSlidersButton.click(resetValues, inputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider],
66
- outputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider])
67
-
68
- clearEXIFCheckbox = gr.Checkbox(label="Clear EXIF (all metadata)")
69
- flipImageCheckbox = gr.Checkbox(label="Flip image")
70
- dontShowOriginalCheckbox = gr.Checkbox(
71
- label="Don't show original image")
72
-
73
- return [saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider,
74
- clearEXIFCheckbox, flipImageCheckbox, dontShowOriginalCheckbox]
75
-
76
- def run(self, p, saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider,
77
- clearEXIFCheckbox, flipImageCheckbox, dontShowOriginalCheckbox):
78
- proc = process_images(p)
79
- image = proc.images[0]
80
- img = ImageEnhance.Color(image).enhance(saturationSlider)
81
- img = ImageEnhance.Brightness(img).enhance(brightnessSlider)
82
- img = ImageEnhance.Contrast(img).enhance(contrastSlider)
83
-
84
- if vignetteSlider > 0:
85
- width, height = img.size
86
- mask = Image.new("L", (width, height), 0)
87
- draw = ImageDraw.Draw(mask)
88
- padding = 100 - vignetteSlider * 100
89
- draw.ellipse((-padding, -padding, width +
90
- padding, height + padding), fill=255)
91
- mask = mask.filter(ImageFilter.GaussianBlur(radius=100))
92
- img = Image.composite(img, Image.new(
93
- "RGB", img.size, "black"), mask)
94
-
95
- if hdrSlider > 0:
96
- blurred = img.filter(ImageFilter.GaussianBlur(radius=2.8))
97
- difference = ImageChops.difference(img, blurred)
98
- sharpEdges = Image.blend(img, difference, 1)
99
-
100
- convertedOriginalImage = np.array(
101
- image)[:, :, ::-1].copy().astype('float32') / 255.0
102
- convertedSharped = np.array(
103
- sharpEdges)[:, :, ::-1].copy().astype('float32') / 255.0
104
-
105
- colorDodge = convertedOriginalImage / (1 - convertedSharped)
106
- convertedColorDodge = (
107
- 255 * colorDodge).clip(0, 255).astype(np.uint8)
108
-
109
- tempImage = Image.fromarray(cv2.cvtColor(
110
- convertedColorDodge, cv2.COLOR_BGR2RGB))
111
- invertedColorDodge = ImageOps.invert(tempImage)
112
- blackWhiteColorDodge = ImageEnhance.Color(
113
- invertedColorDodge).enhance(0)
114
- hue = blendLayers(tempImage, blackWhiteColorDodge, BlendType.HUE)
115
- hdrImage = blendLayers(hue, tempImage, BlendType.NORMAL, .7)
116
-
117
- img = blendLayers(img, hdrImage, BlendType.NORMAL,
118
- hdrSlider * 2).convert("RGB")
119
-
120
- if sharpnessSlider > 0:
121
- img = ImageEnhance.Sharpness(img).enhance(
122
- (sharpnessSlider + 1) * 1.5)
123
-
124
- if blurSlider > 0:
125
- img = img.filter(ImageFilter.BoxBlur(blurSlider * 10))
126
-
127
- if temperatureSlider != 1:
128
- pixels = img.load()
129
- for i in range(img.width):
130
- for j in range(img.height):
131
- (r, g, b) = pixels[i, j]
132
- if temperatureSlider > 1:
133
- r *= 1 + ((temperatureSlider - 1) / 4)
134
- b *= 1 - (((temperatureSlider - 1) / 4))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  else:
136
- r *= 1 - (1 - temperatureSlider) / 4
137
- b *= 1 + (((1 - temperatureSlider) / 4))
138
- pixels[i, j] = (int(r), int(g), int(b))
139
-
140
- if noiseSlider > 0:
141
- noise = np.random.randint(0, noiseSlider * 100, img.size, np.uint8)
142
- noise_img = Image.fromarray(noise, 'L').resize(
143
- img.size).convert(img.mode)
144
- img = ImageChops.add(img, noise_img)
145
-
146
- if exposureOffsetSlider > 0:
147
- np_img = np.array(img).astype(float) + exposureOffsetSlider * 75
148
- np_img = np.clip(np_img, 0, 255).astype(np.uint8)
149
- img = Image.fromarray(np_img)
150
- img = ImageEnhance.Brightness(img).enhance(
151
- brightnessSlider - exposureOffsetSlider / 4)
152
-
153
- if flipImageCheckbox:
154
- img = Image.fromarray(np.fliplr(np.array(img)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
  if dontShowOriginalCheckbox:
157
  proc.images.clear()
158
 
159
- if not clearEXIFCheckbox:
160
- img.info['parameters'] = proc.info
 
 
 
 
161
 
162
- proc.images.insert(0, img)
163
  return Processed(p, proc.images, p.seed, '')
 
5
  import gradio as gr
6
  import numpy as np
7
  import cv2
8
+ import math
9
+ import random
10
+ import modules.images as images
11
 
12
+ from modules.processing import Processed
13
+ from PIL import ImageEnhance, Image, ImageDraw, ImageFilter, ImageChops, ImageOps, ImageFont
 
14
  from blendmodes.blend import blendLayers, BlendType
15
+ from typing import List
16
 
17
 
18
  def resetValues(saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider):
 
43
  return [saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider]
44
 
45
 
46
+ def add_chromatic(im, strength: float = 1, no_blur: bool = False):
47
+
48
+ if (im.size[0] % 2 == 0 or im.size[1] % 2 == 0):
49
+ if (im.size[0] % 2 == 0):
50
+ im = im.crop((0, 0, im.size[0] - 1, im.size[1]))
51
+ im.load()
52
+ if (im.size[1] % 2 == 0):
53
+ im = im.crop((0, 0, im.size[0], im.size[1] - 1))
54
+ im.load()
55
+
56
+ def cartesian_to_polar(data: np.ndarray) -> np.ndarray:
57
+ width = data.shape[1]
58
+ height = data.shape[0]
59
+ assert (width > 2)
60
+ assert (height > 2)
61
+ assert (width % 2 == 1)
62
+ assert (height % 2 == 1)
63
+ perimeter = 2 * (width + height - 2)
64
+ halfdiag = math.ceil(((width ** 2 + height ** 2) ** 0.5) / 2)
65
+ halfw = width // 2
66
+ halfh = height // 2
67
+ ret = np.zeros((halfdiag, perimeter, 3))
68
+
69
+ ret[0:(halfw + 1), halfh] = data[halfh, halfw::-1]
70
+ ret[0:(halfw + 1), height + width - 2 +
71
+ halfh] = data[halfh, halfw:(halfw * 2 + 1)]
72
+ ret[0:(halfh + 1), height - 1 +
73
+ halfw] = data[halfh:(halfh * 2 + 1), halfw]
74
+ ret[0:(halfh + 1), perimeter - halfw] = data[halfh::-1, halfw]
75
+
76
+ for i in range(0, halfh):
77
+ slope = (halfh - i) / (halfw)
78
+ diagx = ((halfdiag ** 2) / (slope ** 2 + 1)) ** 0.5
79
+ unit_xstep = diagx / (halfdiag - 1)
80
+ unit_ystep = diagx * slope / (halfdiag - 1)
81
+ for row in range(halfdiag):
82
+ ystep = round(row * unit_ystep)
83
+ xstep = round(row * unit_xstep)
84
+ if ((halfh >= ystep) and halfw >= xstep):
85
+ ret[row, i] = data[halfh - ystep, halfw - xstep]
86
+ ret[row, height - 1 - i] = data[halfh + ystep, halfw - xstep]
87
+ ret[row, height + width - 2 +
88
+ i] = data[halfh + ystep, halfw + xstep]
89
+ ret[row, height + width + height - 3 -
90
+ i] = data[halfh - ystep, halfw + xstep]
91
+ else:
92
+ break
93
+
94
+ for j in range(1, halfw):
95
+ slope = (halfh) / (halfw - j)
96
+ diagx = ((halfdiag ** 2) / (slope ** 2 + 1)) ** 0.5
97
+ unit_xstep = diagx / (halfdiag - 1)
98
+ unit_ystep = diagx * slope / (halfdiag - 1)
99
+ for row in range(halfdiag):
100
+ ystep = round(row * unit_ystep)
101
+ xstep = round(row * unit_xstep)
102
+ if (halfw >= xstep and halfh >= ystep):
103
+ ret[row, height - 1 + j] = data[halfh + ystep, halfw - xstep]
104
+ ret[row, height + width - 2 -
105
+ j] = data[halfh + ystep, halfw + xstep]
106
+ ret[row, height + width + height - 3 +
107
+ j] = data[halfh - ystep, halfw + xstep]
108
+ ret[row, perimeter - j] = data[halfh - ystep, halfw - xstep]
109
+ else:
110
+ break
111
+ return ret
112
+
113
+ def polar_to_cartesian(data: np.ndarray, width: int, height: int) -> np.ndarray:
114
+ assert (width > 2)
115
+ assert (height > 2)
116
+ assert (width % 2 == 1)
117
+ assert (height % 2 == 1)
118
+ perimeter = 2 * (width + height - 2)
119
+ halfdiag = math.ceil(((width ** 2 + height ** 2) ** 0.5) / 2)
120
+ halfw = width // 2
121
+ halfh = height // 2
122
+ ret = np.zeros((height, width, 3))
123
+
124
+ def div0():
125
+ ret[halfh, halfw::-1] = data[0:(halfw + 1), halfh]
126
+ ret[halfh, halfw:(halfw * 2 + 1)] = data[0:(halfw + 1),
127
+ height + width - 2 + halfh]
128
+ ret[halfh:(halfh * 2 + 1), halfw] = data[0:(halfh + 1),
129
+ height - 1 + halfw]
130
+ ret[halfh::-1, halfw] = data[0:(halfh + 1), perimeter - halfw]
131
+
132
+ div0()
133
+
134
+ def part1():
135
+ for i in range(0, halfh):
136
+ slope = (halfh - i) / (halfw)
137
+ diagx = ((halfdiag ** 2) / (slope ** 2 + 1)) ** 0.5
138
+ unit_xstep = diagx / (halfdiag - 1)
139
+ unit_ystep = diagx * slope / (halfdiag - 1)
140
+ for row in range(halfdiag):
141
+ ystep = round(row * unit_ystep)
142
+ xstep = round(row * unit_xstep)
143
+ if ((halfh >= ystep) and halfw >= xstep):
144
+ ret[halfh - ystep, halfw - xstep] = \
145
+ data[row, i]
146
+ ret[halfh + ystep, halfw - xstep] = \
147
+ data[row, height - 1 - i]
148
+ ret[halfh + ystep, halfw + xstep] = \
149
+ data[row, height + width - 2 + i]
150
+ ret[halfh - ystep, halfw + xstep] = \
151
+ data[row, height + width + height - 3 - i]
152
+ else:
153
+ break
154
+
155
+ part1()
156
+
157
+ def part2():
158
+ for j in range(1, halfw):
159
+ slope = (halfh) / (halfw - j)
160
+ diagx = ((halfdiag ** 2) / (slope ** 2 + 1)) ** 0.5
161
+ unit_xstep = diagx / (halfdiag - 1)
162
+ unit_ystep = diagx * slope / (halfdiag - 1)
163
+ for row in range(halfdiag):
164
+ ystep = round(row * unit_ystep)
165
+ xstep = round(row * unit_xstep)
166
+ if (halfw >= xstep and halfh >= ystep):
167
+ ret[halfh + ystep, halfw - xstep] = \
168
+ data[row, height - 1 + j]
169
+ ret[halfh + ystep, halfw + xstep] = \
170
+ data[row, height + width - 2 - j]
171
+ ret[halfh - ystep, halfw + xstep] = \
172
+ data[row, height + width + height - 3 + j]
173
+ ret[halfh - ystep, halfw - xstep] = \
174
+ data[row, perimeter - j]
175
+ else:
176
+ break
177
+
178
+ part2()
179
+
180
+ def set_zeros():
181
+ zero_mask = ret[1:-1, 1:-1] == 0
182
+ ret[1:-1, 1:-1] = np.where(zero_mask, (ret[:-2,
183
+ 1:-1] + ret[2:, 1:-1]) / 2, ret[1:-1, 1:-1])
184
+
185
+ set_zeros()
186
+
187
+ return ret
188
+
189
+ def get_gauss(n: int) -> List[float]:
190
+ sigma = 0.3 * (n / 2 - 1) + 0.8
191
+ r = range(-int(n / 2), int(n / 2) + 1)
192
+ new_sum = sum([1 / (sigma * math.sqrt(2 * math.pi)) *
193
+ math.exp(-float(x) ** 2 / (2 * sigma ** 2)) for x in r])
194
+ return [(1 / (sigma * math.sqrt(2 * math.pi)) *
195
+ math.exp(-float(x) ** 2 / (2 * sigma ** 2))) / new_sum for x in r]
196
+
197
+ def vertical_gaussian(data: np.ndarray, n: int) -> np.ndarray:
198
+ padding = n - 1
199
+ width = data.shape[1]
200
+ height = data.shape[0]
201
+ padded_data = np.zeros((height + padding * 2, width))
202
+ padded_data[padding: -padding, :] = data
203
+ ret = np.zeros((height, width))
204
+ kernel = None
205
+ old_radius = - 1
206
+ for i in range(height):
207
+ radius = round(i * padding / (height - 1)) + 1
208
+ if (radius != old_radius):
209
+ old_radius = radius
210
+ kernel = np.tile(get_gauss(1 + 2 * (radius - 1)),
211
+ (width, 1)).transpose()
212
+ ret[i, :] = np.sum(np.multiply(
213
+ padded_data[padding + i - radius + 1:padding + i + radius, :], kernel), axis=0)
214
+ return ret
215
+
216
+ r, g, b = im.split()
217
+ rdata = np.asarray(r)
218
+ gdata = np.asarray(g)
219
+ bdata = np.asarray(b)
220
+ if no_blur:
221
+ rfinal = r
222
+ gfinal = g
223
+ bfinal = b
224
+ else:
225
+ poles = cartesian_to_polar(np.stack([rdata, gdata, bdata], axis=-1))
226
+ rpolar, gpolar, bpolar = poles[:, :,
227
+ 0], poles[:, :, 1], poles[:, :, 2],
228
+
229
+ bluramount = (im.size[0] + im.size[1] - 2) / 100 * strength
230
+ if round(bluramount) > 0:
231
+ rpolar = vertical_gaussian(rpolar, round(bluramount))
232
+ gpolar = vertical_gaussian(gpolar, round(bluramount * 1.2))
233
+ bpolar = vertical_gaussian(bpolar, round(bluramount * 1.4))
234
+
235
+ rgbpolar = np.stack([rpolar, gpolar, bpolar], axis=-1)
236
+ cartes = polar_to_cartesian(
237
+ rgbpolar, width=rdata.shape[1], height=rdata.shape[0])
238
+ rcartes, gcartes, bcartes = cartes[:, :,
239
+ 0], cartes[:, :, 1], cartes[:, :, 2],
240
+
241
+ rfinal = Image.fromarray(np.uint8(rcartes), 'L')
242
+ gfinal = Image.fromarray(np.uint8(gcartes), 'L')
243
+ bfinal = Image.fromarray(np.uint8(bcartes), 'L')
244
+
245
+ gfinal = gfinal.resize((round((1 + 0.018 * strength) * rdata.shape[1]),
246
+ round((1 + 0.018 * strength) * rdata.shape[0])), Image.ANTIALIAS)
247
+ bfinal = bfinal.resize((round((1 + 0.044 * strength) * rdata.shape[1]),
248
+ round((1 + 0.044 * strength) * rdata.shape[0])), Image.ANTIALIAS)
249
+
250
+ rwidth, rheight = rfinal.size
251
+ gwidth, gheight = gfinal.size
252
+ bwidth, bheight = bfinal.size
253
+ rhdiff = (bheight - rheight) // 2
254
+ rwdiff = (bwidth - rwidth) // 2
255
+ ghdiff = (bheight - gheight) // 2
256
+ gwdiff = (bwidth - gwidth) // 2
257
+
258
+ im = Image.merge("RGB", (
259
+ rfinal.crop((-rwdiff, -rhdiff, bwidth - rwdiff, bheight - rhdiff)),
260
+ gfinal.crop((-gwdiff, -ghdiff, bwidth - gwdiff, bheight - ghdiff)),
261
+ bfinal))
262
+
263
+ return im.crop((rwdiff, rhdiff, rwidth + rwdiff, rheight + rhdiff))
264
+
265
+
266
+ def tilt_shift(im, dof=60, focus_height=None):
267
+ above_focus, below_focus = im[:focus_height, :], im[focus_height:, :]
268
+ above_focus = increasing_blur(above_focus[::-1, ...], dof)[::-1, ...]
269
+ below_focus = increasing_blur(below_focus, dof)
270
+ out = np.vstack((above_focus, below_focus))
271
+ return out
272
+
273
+ def increasing_blur(im, dof=60):
274
+ blur_region = cv2.GaussianBlur(im[dof:, :], ksize=(15, 15), sigmaX=0)
275
+ if blur_region.shape[0] > dof:
276
+ blur_region = increasing_blur(blur_region, dof)
277
+ blend_col = np.linspace(1.0, 0, num=dof)
278
+ blend_mask = np.tile(blend_col, (im.shape[1], 1)).T
279
+ res = np.zeros_like(im)
280
+ res[:dof, :] = im[:dof, :]
281
+ dof_actual = min(dof, im.shape[0] - dof, blur_region.shape[0])
282
+ blend_mask = blend_mask[:dof_actual, :]
283
+ res[dof:dof + dof_actual, :] = im[dof:dof + dof_actual, :] * blend_mask[:, :, None] + blur_region[:dof_actual, :] * (1 - blend_mask[:, :, None])
284
+ if dof + dof < im.shape[0]:
285
+ res[dof + dof_actual:, :] = blur_region[dof_actual:]
286
+ return res
287
+
288
  class Script(scripts.Script):
289
  def title(self):
290
  return 'Revision'
291
 
292
+ def show(self, is_img2img):
293
+ return scripts.AlwaysVisible
294
+
295
  def ui(self, is_img2img):
296
+ with gr.Accordion('Revision', open=False):
297
+ with gr.Tab(label='Options', id=1):
298
+ enabled = gr.Checkbox(label="Enable")
299
+ clearEXIFCheckbox = gr.Checkbox(label="Clear EXIF (all metadata)")
300
+ flipImageCheckbox = gr.Checkbox(label="Flip image")
301
+ dontShowOriginalCheckbox = gr.Checkbox(label="Don't show original image")
302
+
303
+ with gr.Tab(label='Adjustments', id=2):
304
+ saturationSlider = gr.Slider(0, 2, 1, label='Saturation')
305
+ temperatureSlider = gr.Slider(0, 2, 1, label='Temperature')
306
+ brightnessSlider = gr.Slider(0, 2, 1, label='Brightness')
307
+ contrastSlider = gr.Slider(0, 2, 1, label='Contrast')
308
+ sharpnessSlider = gr.Slider(0, 1, 0, label='Sharpness')
309
+ blurSlider = gr.Slider(0, 1, 0, label='Blur')
310
+ noiseSlider = gr.Slider(0, 1, 0, label='Noise')
311
+ vignetteSlider = gr.Slider(0, 1, 0, step=.05, label='Vignette')
312
+ exposureOffsetSlider = gr.Slider(0, 1, 0, step=.05, label='Exposure offset')
313
+ hdrSlider = gr.Slider(0, 1, 0, label='HDR')
314
+
315
+ bestChoiceButton = gr.Button(value="Best Choice")
316
+ bestChoiceButton.click(bestChoiceValues, inputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider],
317
+ outputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider])
318
+
319
+ resetSlidersButton = gr.Button(value="Reset Sliders")
320
+ resetSlidersButton.click(resetValues, inputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider],
321
+ outputs=[saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider])
322
+
323
+ with gr.Tab(label='Effects', id=3):
324
+ lensDistortionRadioButton = gr.Radio(["None", "Lens Distortion", "Fish Eye"], label="Lens effect", value="None")
325
+ chromaticAberrationSlider = gr.Slider(0, 1, 0, label='Chromatic aberration')
326
+ snowfallSlider = gr.Slider(0, 3000, 0, step=1, label='Snowfall')
327
+ asciiSlider = gr.Slider(0, 20, 0, step=1, label='ASCII')
328
+ tiltShiftRadioButton = gr.Radio(["None", "Top", "Center", "Bottom"], label="Tilt Shift", value="None")
329
+ glitchCheckbox = gr.Checkbox(label="Glitch")
330
+ vhsCheckbox = gr.Checkbox(label="VHS")
331
+ watermark = gr.Textbox(label="Watermark text")
332
+
333
+ with gr.Tab(label='Custom EXIF', id=4):
334
+ customEXIF = gr.TextArea(
335
+ label="Here you can fill in your custom EXIF")
336
+
337
+ return [enabled, saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider,
338
+ clearEXIFCheckbox, flipImageCheckbox, dontShowOriginalCheckbox, lensDistortionRadioButton, chromaticAberrationSlider, customEXIF, tiltShiftRadioButton,
339
+ glitchCheckbox, vhsCheckbox, snowfallSlider, asciiSlider, watermark]
340
+
341
+ def postprocess(self, p, processed, enabled, saturationSlider, temperatureSlider, brightnessSlider, contrastSlider, sharpnessSlider, blurSlider, noiseSlider, vignetteSlider, exposureOffsetSlider, hdrSlider,
342
+ clearEXIFCheckbox, flipImageCheckbox, dontShowOriginalCheckbox, lensDistortionRadioButton, chromaticAberrationSlider, customEXIF, tiltShiftRadioButton,
343
+ glitchCheckbox, vhsCheckbox, snowfallSlider, asciiSlider, watermark):
344
+
345
+ if not enabled:
346
+ return
347
+
348
+ proc = processed
349
+ result = []
350
+
351
+ for i in range(len(proc.images)):
352
+ image = proc.images[i]
353
+ img = ImageEnhance.Color(image).enhance(saturationSlider)
354
+ img = ImageEnhance.Brightness(img).enhance(brightnessSlider)
355
+ img = ImageEnhance.Contrast(img).enhance(contrastSlider)
356
+
357
+ if vignetteSlider > 0:
358
+ width, height = img.size
359
+ mask = Image.new("L", (width, height), 0)
360
+ draw = ImageDraw.Draw(mask)
361
+ padding = 100 - vignetteSlider * 100
362
+ draw.ellipse((-padding, -padding, width +
363
+ padding, height + padding), fill=255)
364
+ mask = mask.filter(ImageFilter.GaussianBlur(radius=100))
365
+ img = Image.composite(img, Image.new(
366
+ "RGB", img.size, "black"), mask)
367
+
368
+ if hdrSlider > 0:
369
+ blurred = img.filter(ImageFilter.GaussianBlur(radius=2.8))
370
+ difference = ImageChops.difference(img, blurred)
371
+ sharpEdges = Image.blend(img, difference, 1)
372
+
373
+ convertedOriginalImage = np.array(
374
+ image)[:, :, ::-1].copy().astype('float32') / 255.0
375
+ convertedSharped = np.array(
376
+ sharpEdges)[:, :, ::-1].copy().astype('float32') / 255.0
377
+
378
+ colorDodge = convertedOriginalImage / (1 - convertedSharped)
379
+ convertedColorDodge = (
380
+ 255 * colorDodge).clip(0, 255).astype(np.uint8)
381
+
382
+ tempImage = Image.fromarray(cv2.cvtColor(
383
+ convertedColorDodge, cv2.COLOR_BGR2RGB))
384
+ invertedColorDodge = ImageOps.invert(tempImage)
385
+ blackWhiteColorDodge = ImageEnhance.Color(
386
+ invertedColorDodge).enhance(0)
387
+ hue = blendLayers(tempImage, blackWhiteColorDodge, BlendType.HUE)
388
+ hdrImage = blendLayers(hue, tempImage, BlendType.NORMAL, .7)
389
+
390
+ img = blendLayers(img, hdrImage, BlendType.NORMAL,
391
+ hdrSlider * 2).convert("RGB")
392
+
393
+ if sharpnessSlider > 0:
394
+ img = ImageEnhance.Sharpness(img).enhance(
395
+ (sharpnessSlider + 1) * 1.5)
396
+
397
+ if blurSlider > 0:
398
+ img = img.filter(ImageFilter.BoxBlur(blurSlider * 10))
399
+
400
+ if temperatureSlider != 1:
401
+ pixels = img.load()
402
+ for i in range(img.width):
403
+ for j in range(img.height):
404
+ (r, g, b) = pixels[i, j]
405
+ if temperatureSlider > 1:
406
+ r *= 1 + ((temperatureSlider - 1) / 4)
407
+ b *= 1 - (((temperatureSlider - 1) / 4))
408
+ else:
409
+ r *= 1 - (1 - temperatureSlider) / 4
410
+ b *= 1 + (((1 - temperatureSlider) / 4))
411
+ pixels[i, j] = (int(r), int(g), int(b))
412
+
413
+ if noiseSlider > 0:
414
+ noise = np.random.randint(0, noiseSlider * 100, img.size, np.uint8)
415
+ noise_img = Image.fromarray(noise, 'L').resize(
416
+ img.size).convert(img.mode)
417
+ img = ImageChops.add(img, noise_img)
418
+
419
+ if exposureOffsetSlider > 0:
420
+ np_img = np.array(img).astype(float) + exposureOffsetSlider * 75
421
+ np_img = np.clip(np_img, 0, 255).astype(np.uint8)
422
+ img = Image.fromarray(np_img)
423
+ img = ImageEnhance.Brightness(img).enhance(
424
+ brightnessSlider - exposureOffsetSlider / 4)
425
+
426
+ if flipImageCheckbox:
427
+ img = Image.fromarray(np.fliplr(np.array(img)))
428
+
429
+ if lensDistortionRadioButton != "None":
430
+ def add_lens_distortion(img, k1, k2):
431
+ img = np.array(img)[:, :, ::-1].copy()
432
+ rows, cols = img.shape[:2]
433
+ map_x, map_y = np.zeros((rows, cols), np.float32), np.zeros(
434
+ (rows, cols), np.float32)
435
+ for i in range(rows):
436
+ for j in range(cols):
437
+ r = np.sqrt((i - rows/2)**2 + (j - cols/2)**2)
438
+ x = j + (j - cols/2) * (k1 * r**2 + k2 * r**4)
439
+ y = i + (i - rows/2) * (k1 * r**2 + k2 * r**4)
440
+ if x >= 0 and x < cols and y >= 0 and y < rows:
441
+ map_x[i, j] = x
442
+ map_y[i, j] = y
443
+ return cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR)
444
+
445
+ if lensDistortionRadioButton == "Lens Distortion":
446
+ img = add_lens_distortion(img, 1e-12, -1e-12)
447
+ else:
448
+ img = add_lens_distortion(img, 1e-12, 1e-12)
449
+ img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
450
+
451
+ if chromaticAberrationSlider > 0:
452
+ img = add_chromatic(img, chromaticAberrationSlider + .12, True)
453
+
454
+ if tiltShiftRadioButton != "None":
455
+ width, height = img.size
456
+ ratio = 1/5 if tiltShiftRadioButton == "Top" else 1 / \
457
+ 2 if tiltShiftRadioButton == "Center" else 4/5
458
+ img = Image.fromarray(cv2.cvtColor(tilt_shift(np.array(
459
+ img)[:, :, ::-1].copy(), 60, round(height * ratio)), cv2.COLOR_BGR2RGB))
460
+
461
+ if glitchCheckbox:
462
+ img = np.array(img)[:, :, ::-1].copy()
463
+ num_glitches = 5
464
+ height, width = img.shape[:2]
465
+
466
+ for _ in range(num_glitches):
467
+ y = np.random.randint(height)
468
+ h = np.random.randint(10, 50)
469
+ y1 = np.clip(y - h // 2, 0, height)
470
+ y2 = np.clip(y + h // 2, 0, height)
471
+ w = np.random.randint(20, width // 4)
472
+ channel = np.random.randint(0, 3)
473
+ img[y1:y2, w:, channel] = img[y1:y2, :-w, channel]
474
+ img[y1:y2, :w, channel] = np.random.randint(0, 256, (y2 - y1, w), dtype=np.uint8)
475
+
476
+ img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
477
+
478
+ if vhsCheckbox:
479
+ # Коррекция насыщености, яркости и контрастности
480
+ img = ImageEnhance.Color(img).enhance(0.88)
481
+ img = ImageEnhance.Brightness(img).enhance(1.06)
482
+ img = ImageEnhance.Contrast(img).enhance(0.88)
483
+
484
+ # Цветной шум
485
+ noise = np.random.normal(loc=128, scale=128, size=img.size[::-1] + (3,)).clip(0, 255).astype(np.uint8)
486
+ dust_and_scratches = Image.fromarray(noise, 'RGB').filter(ImageFilter.GaussianBlur(1))
487
+ img = Image.blend(img, dust_and_scratches, alpha=0.02)
488
+
489
+ # Размытие в движении
490
+ img = np.array(img)[:, :, ::-1].copy()
491
+ size = 4
492
+ kernel = np.zeros((size, size))
493
+ kernel[int((size-1)/2), :] = np.ones(size)
494
+ kernel = kernel / size
495
+ img = cv2.filter2D(img, -1, kernel)
496
+ img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
497
+
498
+ # Резкость
499
+ img = ImageEnhance.Sharpness(img).enhance((1.2))
500
+
501
+ # Тиснение
502
+ img = blendLayers(img, img.filter(ImageFilter.EMBOSS()), BlendType.HARDLIGHT, 1.8)
503
+
504
+ # Glitch от плёнки
505
+ img = np.array(img)[:, :, ::-1].copy()
506
+ num_glitches = 5
507
+ height, width = img.shape[:2]
508
+ for _ in range(num_glitches):
509
+ y = np.random.randint(height)
510
+ h = np.random.randint(1, 3)
511
+ y1 = np.clip(y - h // 2, 0, height)
512
+ y2 = np.clip(y + h // 2, 0, height)
513
+ w = np.random.randint(20, width // 4)
514
+ channel = np.random.randint(0, 3)
515
+ img[y1:y2, w:, channel] = img[y1:y2, :-w, channel]
516
+ img[y1:y2, :w, channel] = np.random.randint(100, 156, (y2 - y1, w), dtype=np.uint8)
517
+
518
+ img = Image.fromarray(img[:, :, ::-1])
519
+
520
+ if snowfallSlider > 0:
521
+ img = np.array(img)[:, :, ::-1].copy()
522
+ height, width = img.shape[:2]
523
+ num_snowflakes = snowfallSlider
524
+
525
+ first_snow_layer = np.zeros_like(img)
526
+ second_snow_layer = np.zeros_like(img)
527
+
528
+ for _ in range(num_snowflakes):
529
+ center_x, center_y = random.randint(0, width - 1), random.randint(0, height - 1)
530
+ num_vertices = random.randint(3, 6)
531
+ radius = random.randint(1, 3)
532
+
533
+ polygon = np.array([[
534
+ center_x + random.randint(-radius, radius),
535
+ center_y + random.randint(-radius, radius)
536
+ ] for _ in range(num_vertices)], np.int32)
537
+ polygon = polygon.reshape((-1, 1, 2))
538
+ blur = random.choice([True, False])
539
+
540
+ if blur:
541
+ cv2.fillPoly(second_snow_layer, [polygon], (255, 255, 255))
542
  else:
543
+ cv2.fillPoly(first_snow_layer, [polygon], (255, 255, 255))
544
+
545
+ first_snow_layer = cv2.GaussianBlur(first_snow_layer, (5, 5), 0)
546
+ second_snow_layer = cv2.GaussianBlur(second_snow_layer, (15, 15), 0)
547
+
548
+ snowy_img = cv2.addWeighted(img, 1, first_snow_layer, 1, 0)
549
+ img = cv2.addWeighted(snowy_img, 1, second_snow_layer, 1, 0)
550
+ img = Image.fromarray(img[:, :, ::-1])
551
+
552
+ if asciiSlider > 0:
553
+ chars = " .'`^\",:;I1!i><-+_-?][}{1)(|\/tfjrxnuvczXYUCLQ0OZmwqpbdkhao*#MW&8%B@$"
554
+ small_image = img.resize((img.width // asciiSlider, img.height // asciiSlider), Image.Resampling.NEAREST)
555
+ ascii_image = Image.new('RGB', img.size, 'black')
556
+ font = ImageFont.truetype("arial.ttf", asciiSlider)
557
+ draw = ImageDraw.Draw(ascii_image)
558
+
559
+ for i in range(small_image.height):
560
+ for j in range(small_image.width):
561
+ pixel = small_image.getpixel((j, i))
562
+ gray = sum(pixel) // 3
563
+ char = chars[gray * len(chars) // 256]
564
+ draw.text((j * asciiSlider, i * asciiSlider), char, font=font, fill=pixel)
565
+
566
+ img = ascii_image
567
+
568
+ if len(watermark) > 0:
569
+ tempImg = Image.new('RGBA', (img.width, img.height), (0, 0, 0, 0))
570
+ draw = ImageDraw.Draw(tempImg)
571
+
572
+ userText = watermark.upper()
573
+ textSize = round(img.width / 5)
574
+ font = ImageFont.truetype('impact.ttf', textSize)
575
+ text_width, text_height = draw.textsize(userText, font)
576
+ right = (img.width - text_width) - 35
577
+ bottom = (img.height - text_height) - img.height / 3
578
+
579
+ shadowcolor = (111, 0, 0)
580
+ draw.text((right + (textSize / 48), bottom + (textSize / 48)), userText,
581
+ font=font, fill=shadowcolor)
582
+
583
+ textcolor = (20, 25, 30)
584
+ draw.text((right, bottom), userText, font=font, fill=textcolor)
585
+
586
+ tempImg = tempImg.transform(tempImg.size, Image.AFFINE, (
587
+ 1, 0, 0, 0.1, 1, 0), resample=Image.BICUBIC, fillcolor=(0, 0, 0, 0))
588
+
589
+ img_arr = np.array(tempImg)
590
+ mask = np.random.randint(
591
+ 0, 2, size=img_arr.shape[:2]).astype(bool)
592
+ mask = np.repeat(mask[:, :, np.newaxis], 4, axis=2)
593
+
594
+ img_arr[mask] = img_arr[np.roll(mask, 5, axis=1)]
595
+ tempImg = Image.fromarray(img_arr)
596
+
597
+ img = blendLayers(img, tempImg, BlendType.NORMAL, .44)
598
+
599
+ if not clearEXIFCheckbox:
600
+ img.info['parameters'] = proc.info
601
+
602
+ if len(customEXIF) > 0:
603
+ img.info['parameters'] = customEXIF
604
+
605
+ result.append(img)
606
 
607
  if dontShowOriginalCheckbox:
608
  proc.images.clear()
609
 
610
+ for i in result:
611
+ proc.images.append(i)
612
+ try:
613
+ images.save_image(i, p.outpath_samples, "", info=i.info['parameters'])
614
+ except:
615
+ images.save_image(i, p.outpath_samples, "", info='')
616
 
 
617
  return Processed(p, proc.images, p.seed, '')
user.js CHANGED
@@ -1,53 +1,67 @@
1
  // Custom scripts by XpucT
2
  // Homepage: https://boosty.to/xpuct
3
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- document.addEventListener('keydown', function (e) {
 
6
 
7
- // Reload UI по F2
8
- if (e.code === 'F2') {
9
- document.querySelector('#settings_restart_gradio').click()
 
10
  e.preventDefault()
 
11
 
12
- // Показать предыдущую генерацию по клавише Shift
13
- } else if (e.keyCode === 16 && document.querySelector('.livePreview'))
14
- document.querySelector('.livePreview').style.display = 'none'
15
- });
 
 
 
16
 
17
- document.addEventListener('keyup', function (e) {
18
- if (e.keyCode === 16 && document.querySelector('.livePreview')) {
 
 
19
  document.querySelector('.livePreview').style.display = 'block'
20
  }
21
- });
22
 
23
- onUiLoaded(function () {
24
-
25
- // Удаление рекламы в Photopea (работает не всегда)
26
  const result = document.evaluate("//div[@class='flexrow app']/div[2]", document, null, XPathResult.ANY_TYPE, null)
27
  var ad = result.iterateNext()
28
- while (ad) {
 
29
  ad.parentNode.removeChild(ad)
30
  ad = result.iterateNext()
31
  }
32
-
33
- // Граница в txt2img немного левее, а не посередине
34
- document.querySelector('gradio-app .resize-handle-row').style.gridTemplateColumns = '676px 16px 1fr'
35
-
36
- // Вставить выбранные стили колесом
37
- document.querySelectorAll('button[id$=_styles_edit_button]').forEach(x =>
38
- x.addEventListener('mousedown', e =>
39
- e.button === 1 && get_uiCurrentTabContent().querySelector('button[id$=_style_apply]').click()))
40
- })
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
 
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  // Custom scripts by XpucT
2
  // Homepage: https://boosty.to/xpuct
3
 
4
+ document.addEventListener('keydown', function(e)
5
+ {
6
+ // Показать предыдущую генерацию по клавише Shift
7
+ if (e.keyCode === 16 && document.querySelector('.livePreview'))
8
+ document.querySelector('.livePreview').style.display = 'none'
9
+
10
+ // Переключить Mask Mode по Ctrl + F2
11
+ else if (e.ctrlKey && e.code === 'F2')
12
+ {
13
+ const commonRadio = document.querySelector('#img2img_mask_mode').children[2]
14
+ commonRadio.children[0].className.includes('selected') ? commonRadio.children[1].click() : commonRadio.children[0].click()
15
 
16
+ e.preventDefault()
17
+ }
18
 
19
+ // Выгрузить модели по F4
20
+ else if (e.code === 'F4')
21
+ {
22
+ document.querySelector('#sett_unload_sd_model').click()
23
  e.preventDefault()
24
+ }
25
 
26
+ // Reload UI по F2
27
+ else if (e.code === 'F2')
28
+ {
29
+ document.querySelector('#settings_restart_gradio').click()
30
+ e.preventDefault()
31
+ }
32
+ })
33
 
34
+ document.addEventListener('keyup', function(e)
35
+ {
36
+ if (e.keyCode === 16 && document.querySelector('.livePreview'))
37
+ {
38
  document.querySelector('.livePreview').style.display = 'block'
39
  }
40
+ })
41
 
42
+ onUiLoaded(function()
43
+ {
44
+ // Удаление рекламы в Photopea (работает не всегда)
45
  const result = document.evaluate("//div[@class='flexrow app']/div[2]", document, null, XPathResult.ANY_TYPE, null)
46
  var ad = result.iterateNext()
47
+ while (ad)
48
+ {
49
  ad.parentNode.removeChild(ad)
50
  ad = result.iterateNext()
51
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
 
54
+ // Граница в txt2img немного левее, а не посередине
55
+ document.querySelector('gradio-app .resize-handle-row').style.gridTemplateColumns = '676px 16px 1fr'
56
+
57
+ document.querySelectorAll('button[id$=_generate]').forEach((x) => x.addEventListener('mousedown', (e) =>
58
+ {
59
+ if (e.button === 1)
60
+ {
61
+ get_uiCurrentTabContent().querySelector('div[id$=_adetailer_ad_enable]').children[1].click()
62
+ get_uiCurrentTabContent().querySelector('button[id$=_generate]').click()
63
+ setTimeout(() => get_uiCurrentTabContent().querySelector('div[id$=_adetailer_ad_enable]').children[1].click(), 100)
64
+ e.preventDefault()
65
+ }
66
+ }))
67
+ })