|
from PIL import Image,features |
|
import modules.scripts as scripts |
|
from modules import images |
|
from modules.processing import process_images |
|
from modules.shared import opts |
|
import io |
|
import gradio as gr |
|
import subprocess |
|
import os |
|
import sys |
|
|
|
|
|
|
|
class Script(scripts.Script): |
|
def __init__(self): |
|
self.script_dir = os.path.dirname(os.path.realpath(__name__))+os.sep+'scripts'+os.sep |
|
self.nQuant = 'nQuantCpp.exe' |
|
self.palette_algos = ['PNN', 'PNNLAB', 'NEU', 'WU', 'EAS', 'SPA', 'DIV', 'DL3', 'MMC','Median', 'Maximum Coverage', 'Octree'] |
|
self.color_palletes = ['Automatic','NES'] |
|
def title(self): |
|
return "PXL8" |
|
def show(self, is_img2img): |
|
return True |
|
|
|
def ui(self, is_img2img): |
|
with gr.Row(): |
|
dither = gr.Checkbox(True, label="Dither") |
|
rescale = gr.Checkbox(True, label="Rescale to original size") |
|
rescale_before = gr.Checkbox(True, label="Rescale before quantize") |
|
with gr.Row(): |
|
downscale = gr.Slider(minimum=1, maximum=64, step=1, value=8, label="Downscale multiplier") |
|
color_pal_size = gr.Slider(minimum=0, maximum=256, step=1, value=16, label="Color palette size") |
|
if features.check_feature("libimagequant"): |
|
self.palette_algos.insert(0, "libimagequant") |
|
palette_algo = gr.Radio(choices=self.palette_algos, value=self.palette_algos[0], label='Palette Extraction Algorithm') |
|
|
|
|
|
|
|
|
|
return [downscale,rescale,rescale_before,color_pal_size,palette_algo,dither] |
|
|
|
def run(self, p, downscale,rescale,rescale_before,color_pal_size,palette_algo,dither): |
|
def process(im): |
|
isDither = 1 if dither else 0 |
|
isSmart = 1 if palette_algo in self.palette_algos[:9] else 0 |
|
|
|
temp = os.path.join(self.script_dir,"temp.png") |
|
out_width, out_height = im.size |
|
sample_width = int(out_width / downscale) |
|
sample_height = int(out_height / downscale) |
|
if rescale_before: |
|
work = im.resize((sample_width, sample_height), Image.NEAREST) |
|
else: |
|
work = im |
|
if color_pal_size != 0: |
|
if isSmart == 0: |
|
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 |
|
work = work.convert("RGB").quantize(colors=int(color_pal_size), method=method, dither=Image.Dither.FLOYDSTEINBERG if isDither else 0) |
|
else: |
|
work = work.convert("RGB") |
|
work.save(temp) |
|
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) |
|
s_t = os.path.join(self.script_dir,f"temp-{palette_algo}quant{color_pal_size}.png") |
|
|
|
work = Image.open(s_t).convert("RGB") |
|
os.remove(s_t) |
|
os.remove(temp) |
|
if rescale_before == False: |
|
work = work.resize((sample_width, sample_height), Image.NEAREST) |
|
if rescale: |
|
work = work.resize((out_width, out_height), Image.NEAREST) |
|
return work |
|
out = process_images(p) |
|
for i in range(len(out.images)): |
|
out.images[i] = process(out.images[i]) |
|
images.save_image(out.images[i], p.outpath_samples, "", out.seed + i, out.prompt, opts.samples_format, info= out.info, p=p) |
|
return out |