Spaces:
Sleeping
Sleeping
| import spaces | |
| import gradio as gr | |
| import re | |
| from PIL import Image,ImageEnhance | |
| import os | |
| import numpy as np | |
| import hashlib | |
| import io | |
| import cv2 | |
| import time | |
| def clear_old_files(dir,passed_time): | |
| files = os.listdir(dir) | |
| current_time = time.time() | |
| for file in files: | |
| file_path = os.path.join(dir,file) | |
| ctime = os.stat(file_path).st_ctime | |
| diff = current_time - ctime | |
| print(f"ctime={ctime},current_time={current_time},passed_time={passed_time},diff={diff}") | |
| if diff > passed_time: | |
| os.remove(file_path) | |
| print(f"file removed {file_path}")#TODO remove later | |
| def get_image_id(image): | |
| buffer = io.BytesIO() | |
| image.save(buffer, format='PNG') | |
| hash_object = hashlib.sha256(buffer.getvalue()) | |
| hex_dig = hash_object.hexdigest() | |
| unique_id = hex_dig[:32] | |
| return unique_id | |
| dir_name ="images" | |
| passed_time = 60*3 | |
| def process_create_webp(images,duration=100, loop=0,quality=85): | |
| frames = [] | |
| for image_file in images: | |
| frames.append(image_file) | |
| output_buffer = io.BytesIO() | |
| frames[0].save(output_buffer, | |
| save_all=True, | |
| append_images=frames[1:], | |
| duration=duration, | |
| loop=loop, | |
| format='WebP', | |
| quality=quality | |
| ) | |
| return output_buffer.getvalue() | |
| def process_create_apng(images,duration=100, disposal=1,blend=0,loop=0): | |
| frames = [] | |
| for image_file in images: | |
| frames.append(image_file) | |
| output_buffer = io.BytesIO() | |
| frames[0].save(output_buffer, | |
| save_all=True, | |
| append_images=frames[1:], | |
| #duration=duration, disposal=0,blend=1, | |
| duration=duration, disposal=disposal,blend=blend, | |
| loop=loop, | |
| format='png') | |
| return output_buffer.getvalue() | |
| def process_create_gif(images,duration=100, quantize=False,disposal=1,blend=0,loop=0): | |
| frames = [] | |
| for image_file in images: | |
| if quantize: | |
| image_file = image_file.quantize(colors=256, method=2) | |
| #image_file = image_file.quantize() | |
| frames.append(image_file) | |
| output_buffer = io.BytesIO() | |
| frames[0].save(output_buffer, | |
| save_all=True, | |
| append_images=frames[1:], | |
| #duration=duration, disposal=0,blend=1, | |
| duration=duration, disposal=disposal,blend=blend, | |
| loop=loop, | |
| format='gif', | |
| optimize=False | |
| #dither=Image.FLOYDSTEINBERG | |
| ) | |
| return output_buffer.getvalue() | |
| def save_to_image(image,extension="png",quality=0.8): | |
| id = get_image_id(image) | |
| path = os.path.join(dir_name,f"{id}.{extension}") | |
| if extension == "jpg" or extension == "jpeg" or extension == "webp": | |
| image.convert("RGB").save(path,quality=quality) | |
| else: | |
| image.save(path) | |
| return path | |
| def convert_webp_to_images(webp_path): | |
| # add list | |
| frames = [] | |
| durations = [] | |
| Image.init() | |
| image = Image.open(webp_path) | |
| if hasattr(image,"n_frames"): | |
| for i in range(image.n_frames): | |
| image.seek(i) | |
| frame = image.copy() | |
| frames.append(frame) | |
| # frame.info must be dictionary | |
| duration = frame.info.get("duration",100) | |
| durations.append(duration) | |
| else:# webp never happen? | |
| frames.append(image) | |
| durations.append(100)#default | |
| return frames,durations | |
| def buffer_to_id(buffer_value): | |
| hash_object = hashlib.sha256(buffer_value) | |
| hex_dig = hash_object.hexdigest() | |
| unique_id = hex_dig[:32] | |
| return unique_id | |
| def process_images(input_path,same_size=False,image_width=128,file_format="webp",webp_quality=85): | |
| if input_path == None: | |
| raise gr.Error("need image") | |
| # cache control | |
| if not os.path.exists(dir_name): | |
| os.mkdir(dir_name) | |
| clear_old_files(dir_name,passed_time) | |
| images =[] | |
| frames,durations = convert_webp_to_images(input_path) | |
| new_frames = [] | |
| new_width,new_height = frames[0].size | |
| if not same_size and image_width!=new_width: | |
| ratio = new_height/new_width | |
| new_height = int(image_width*ratio) | |
| new_width = image_width | |
| #print(f"ratio = {ratio} new size {new_width} x {new_height}") | |
| for frame in frames: | |
| new_frame = frame.resize((new_width,new_height))# extremly slow Image.LANCZOS | |
| new_frames.append(new_frame) | |
| else: | |
| new_frames = frames | |
| if file_format == "webp": | |
| webp_buffer = process_create_webp(new_frames,durations,webp_quality) | |
| webp_id = buffer_to_id(webp_buffer) | |
| webp_path = os.path.join(dir_name,f"{webp_id}.webp") | |
| with open(webp_path, 'wb') as f: | |
| f.write(webp_buffer) | |
| images.append((webp_path,"webp")) | |
| elif file_format == "apng": | |
| apng_buffer = process_create_apng(new_frames,durations) | |
| apng_id = buffer_to_id(apng_buffer) | |
| apng_path = os.path.join(dir_name,f"{apng_id}.apng") | |
| with open(apng_path, 'wb') as f: | |
| f.write(apng_buffer) | |
| images.append((apng_path,"apng")) | |
| elif file_format == "gif": | |
| gif_buffer = process_create_gif(new_frames,durations,False) | |
| gif_id = buffer_to_id(gif_buffer) | |
| gif_path = os.path.join(dir_name,f"{gif_id}.gif") | |
| with open(gif_path, 'wb') as f: | |
| f.write(gif_buffer) | |
| images.append((gif_path,"gif")) | |
| else: | |
| f,extension = file_format.split("-") | |
| for i ,frame in enumerate(new_frames): | |
| path = save_to_image(frame,extension,webp_quality) | |
| images.append((path,f"index {i}")) | |
| return images | |
| def read_file(path: str) -> str: | |
| with open(path, 'r', encoding='utf-8') as f: | |
| content = f.read() | |
| return content | |
| def test_echo(param): | |
| return param | |
| def samesize_changed(check,slider): | |
| return gr.Slider(label="Image Width", | |
| minimum=8, | |
| maximum=2048, | |
| step=1, | |
| value=slider, | |
| interactive=not check) | |
| css=""" | |
| #col-left { | |
| margin: 0 auto; | |
| max-width: 640px; | |
| } | |
| #col-right { | |
| margin: 0 auto; | |
| max-width: 640px; | |
| } | |
| .grid-container { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap:10px | |
| } | |
| .image { | |
| width: 128px; | |
| height: 128px; | |
| object-fit: cover; | |
| } | |
| } | |
| } | |
| .text { | |
| font-size: 16px; | |
| } | |
| """ | |
| js = """ | |
| function(path){ | |
| console.log(path) | |
| return path | |
| } | |
| """ | |
| with gr.Blocks(css=css, elem_id="demo-container") as demo: | |
| with gr.Column(): | |
| gr.HTML(read_file("demo_header.html")) | |
| gr.HTML(read_file("demo_tools.html")) | |
| with gr.Row(): | |
| with gr.Column(): | |
| file = gr.File(label="WebP Upload") | |
| image = gr.Image(sources=[],image_mode='RGB', elem_id="Image", type="filepath", label="Preview WebP") | |
| #file.select(fn=test_echo,inputs=[file]) | |
| file.upload(fn=test_echo,inputs=[file],outputs=[image]) | |
| file.clear(fn=test_echo,inputs=[file],outputs=[image]) | |
| btn = gr.Button("Convert", elem_id="run_button",variant="primary") | |
| # type choice | |
| # size slider | |
| file_format=gr.Dropdown( | |
| ["webp", "apng", "gif","images-png","images-jpg"], label="Animation Format", info="Convert to Animattion" ) | |
| same_size = gr.Checkbox(label="Same Size",value=False) | |
| image_width = gr.Slider( | |
| label="Image Width",info = "new animation size", | |
| minimum=8, | |
| maximum=2048, | |
| step=1, | |
| value=128, | |
| interactive=True) | |
| same_size.change(fn=samesize_changed,inputs=[same_size,image_width],outputs=[image_width]) | |
| with gr.Accordion(label="Advanced Settings", open=False): | |
| with gr.Row( equal_height=True): | |
| webp_quality = gr.Slider( | |
| label="WebP Quality",info = "this change file size", | |
| minimum=0, | |
| maximum=100, | |
| step=1, | |
| value=85, | |
| interactive=True) | |
| with gr.Column(): | |
| image_out = gr.Gallery(height=800,label="Output", elem_id="output-img",format="webp", columns=[4],rows=[2],preview=True) | |
| btn.click(fn=process_images, inputs=[file,same_size,image_width,file_format,webp_quality], outputs =[image_out], api_name='infer') | |
| gr.Examples( | |
| examples=[ | |
| ["examples/1024.webp","examples/1024.webp"], | |
| #["images/00346245_00006200.jpg", "images/00346245_00003200.jpg","images/00346245_mask.jpg",10,0,"images/00346245_mixed.jpg"] | |
| ] | |
| , | |
| inputs=[image,file]#example not fire event | |
| ) | |
| gr.HTML(read_file("demo_footer.html")) | |
| if __name__ == "__main__": | |
| demo.launch() | |