Upload 2 files
Browse filesDownload the script and exe and place them in your script folder or download the zip and extract it there.
Select PXL8 from the scripts menu in Auto's WebUI.
Dream big, and make some art!
- nQuantCpp.exe +0 -0
- pixl8.py +77 -0
nQuantCpp.exe
ADDED
Binary file (266 kB). View file
|
|
pixl8.py
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image,features
|
2 |
+
import modules.scripts as scripts
|
3 |
+
from modules import images
|
4 |
+
from modules.processing import process_images
|
5 |
+
from modules.shared import opts
|
6 |
+
import io
|
7 |
+
import gradio as gr
|
8 |
+
import subprocess
|
9 |
+
import os
|
10 |
+
import sys
|
11 |
+
|
12 |
+
#https://github.com/mcychan/nQuantCpp licensed under the GNU General Public License v3.0
|
13 |
+
|
14 |
+
class Script(scripts.Script):
|
15 |
+
def __init__(self):
|
16 |
+
self.script_dir = os.path.dirname(os.path.realpath(__name__))+os.sep+'scripts'+os.sep
|
17 |
+
self.nQuant = 'nQuantCpp.exe'
|
18 |
+
self.palette_algos = ['PNN', 'PNNLAB', 'NEU', 'WU', 'EAS', 'SPA', 'DIV', 'DL3', 'MMC','Median', 'Maximum Coverage', 'Octree']
|
19 |
+
self.color_palletes = ['Automatic','NES']
|
20 |
+
def title(self):
|
21 |
+
return "PXL8"
|
22 |
+
def show(self, is_img2img):
|
23 |
+
return True
|
24 |
+
|
25 |
+
def ui(self, is_img2img):
|
26 |
+
with gr.Row():
|
27 |
+
dither = gr.Checkbox(True, label="Dither")
|
28 |
+
rescale = gr.Checkbox(True, label="Rescale to original size")
|
29 |
+
rescale_before = gr.Checkbox(True, label="Rescale before quantize")
|
30 |
+
with gr.Row():
|
31 |
+
downscale = gr.Slider(minimum=1, maximum=64, step=1, value=8, label="Downscale multiplier")
|
32 |
+
color_pal_size = gr.Slider(minimum=0, maximum=256, step=1, value=16, label="Color palette size")
|
33 |
+
if features.check_feature("libimagequant"):
|
34 |
+
self.palette_algos.insert(0, "libimagequant")
|
35 |
+
palette_algo = gr.Radio(choices=self.palette_algos, value=self.palette_algos[0], label='Palette Extraction Algorithm')
|
36 |
+
|
37 |
+
#add dropdown for color palletes
|
38 |
+
#custom_palette = gr.Dropdown(choices=self.color_palletes, label="Custom Palette")
|
39 |
+
|
40 |
+
return [downscale,rescale,rescale_before,color_pal_size,palette_algo,dither]
|
41 |
+
|
42 |
+
def run(self, p, downscale,rescale,rescale_before,color_pal_size,palette_algo,dither):
|
43 |
+
def process(im):
|
44 |
+
isDither = 1 if dither else 0
|
45 |
+
isSmart = 1 if palette_algo in self.palette_algos[:9] else 0
|
46 |
+
#isCustomPalette = 1 if custom_palette != "None" else 0
|
47 |
+
temp = os.path.join(self.script_dir,"temp.png")
|
48 |
+
out_width, out_height = im.size
|
49 |
+
sample_width = int(out_width / downscale)
|
50 |
+
sample_height = int(out_height / downscale)
|
51 |
+
if rescale_before:
|
52 |
+
work = im.resize((sample_width, sample_height), Image.NEAREST)
|
53 |
+
else:
|
54 |
+
work = im
|
55 |
+
if color_pal_size != 0:
|
56 |
+
if isSmart == 0:
|
57 |
+
method = Image.Quantize.MEDIANCUT if palette_algo == 'Median' else Image.Quantize.MAXCOVERAGE if palette_algo == 'Maximum Coverage' else Image.Quantize.FASTOCTREE if palette_algo == 'Octree' else Image.Quantize.LIBIMAGEQUANT
|
58 |
+
work = work.convert("RGB").quantize(colors=int(color_pal_size), method=method, dither=Image.Dither.FLOYDSTEINBERG if isDither else 0)
|
59 |
+
else:
|
60 |
+
work = work.convert("RGB")
|
61 |
+
work.save(temp)
|
62 |
+
run = subprocess.run([os.path.join(self.script_dir, self.nQuant), temp, f"/m ",str(color_pal_size), f"/a ",palette_algo, "/d ","y" if isDither==1 else "n",], stdout=subprocess.DEVNULL)
|
63 |
+
s_t = os.path.join(self.script_dir,f"temp-{palette_algo}quant{color_pal_size}.png")
|
64 |
+
#open s_t without holding it open
|
65 |
+
work = Image.open(s_t).convert("RGB")
|
66 |
+
os.remove(s_t)
|
67 |
+
os.remove(temp)
|
68 |
+
if rescale_before == False:
|
69 |
+
work = work.resize((sample_width, sample_height), Image.NEAREST)
|
70 |
+
if rescale:
|
71 |
+
work = work.resize((out_width, out_height), Image.NEAREST)
|
72 |
+
return work
|
73 |
+
out = process_images(p)
|
74 |
+
for i in range(len(out.images)):
|
75 |
+
out.images[i] = process(out.images[i])
|
76 |
+
images.save_image(out.images[i], p.outpath_samples, "", out.seed + i, out.prompt, opts.samples_format, info= out.info, p=p)
|
77 |
+
return out
|