Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
soni-shashan authored Jan 30, 2024
0 parents commit d792308
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 0 deletions.
109 changes: 109 additions & 0 deletions boot_to_gif.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'''
project-name=GIF TO BOOT ANIMATION
DATE=30-01-2024
DEVLOPER=SHASHAN SONI
https://github.com/soni-shashan/
'''

from customtkinter import *
from tkinter import filedialog
import threading
import sys
import os
import shutil
import signal
import create_boot_animation

def goTo():
if create_boot_animation.create(file_path,width,hight,fps,'OUTPUT'):
os.remove('OUTPUT/desc.txt')
shutil.rmtree('OUTPUT/part0')
information.destroy()
app.quit()

def click_sumbit():
global width,hight,fps
if width_entry.get()!="":
width=width_entry.get()
if not isinstance(width,int):
width=int(width)
else:
width=1024
if hight_entry.get()!="":
hight=hight_entry.get()
if not isinstance(hight,int):
hight=int(hight)
else:
hight=600
if fps_entry.get()!="":
fps=fps_entry.get()
if not isinstance(fps,int):
fps=int(fps)
else:
fps=60

global command,information,file_path
file_path=file_path.replace("/","\\\\")
command=f"{sys._MEIPASS}/python {sys._MEIPASS}/create_boot_animation.py \"{file_path}\" {width} {hight} {fps} output -zip"
label.destroy()
width_text.destroy()
width_entry.destroy()
hight_text.destroy()
hight_entry.destroy()
fps_label.destroy()
fps_entry.destroy()
create_btn.destroy()
information=CTkLabel(app,text="Please wait!! it may take 5-10 seconds.",fg_color="transparent",font=('arial',16))
information.place(relx=0.5,rely=0.5,anchor="center")
therde=threading.Thread(target=goTo)
therde.start()

def select_gif_file():
global file_path,width_entry,hight_entry,fps_entry,label,width_text,hight_text,fps_entry,create_btn,fps_label
file_path = filedialog.askopenfilename(filetypes=[("GIF files", "*.gif")])
# Do something with the selected GIF file path (e.g., display it, process it, etc.)
if file_path!="":
print("Selected GIF file: ", file_path)
btn.destroy()

label = CTkLabel(app, text="Selected GIF file: "+ file_path, fg_color="transparent",font=('arial',14))
label.place(relx=0.5, rely=0.1, anchor="center")

width_text=CTkLabel(app,text="WIDTH (DEFUALT: 1024)",fg_color="transparent",font=('arial',16))
width_text.place(relx=0.5,rely=0.15,anchor="center")

width_entry=CTkEntry(app,width=170,text_color="#000000")
width_entry.place(relx=0.5,rely=0.22,anchor="center")

hight_text=CTkLabel(app,text="HIGHT (DEFUALT: 600)",fg_color="transparent",font=('arial',16))
hight_text.place(relx=0.5,rely=0.3,anchor="center")

hight_entry=CTkEntry(app,width=170,text_color="#000000")
hight_entry.place(relx=0.5,rely=0.37,anchor="center")

fps_label=CTkLabel(app,text="FPS (DEFUALT: 60)",fg_color="transparent",font=('arial',16))
fps_label.place(relx=0.5,rely=0.45,anchor="center")

fps_entry=CTkEntry(app,width=170,text_color="#000000")
fps_entry.place(relx=0.5,rely=0.52,anchor="center")

create_btn=CTkButton(master=app,text='CREATE',corner_radius=20,fg_color="#C850C0",hover_color="#4158D0",border_color="#000000",border_width=2,width=150,height=50,command=click_sumbit)
create_btn.place(relx=0.5,rely=0.65,anchor="center")
width_entry.focus_set()

def on_closing():
os.kill(os.getpid(), signal.SIGINT)
sys.exit()

if __name__=='__main__':
app=CTk()
app.geometry("512x512")
app.minsize(512,512)
app.maxsize(512,512)
app.title('GIF TO BOOT ANIMATITON')
app.protocol("WM_DELETE_WINDOW", on_closing)
set_appearance_mode("light")
app.iconbitmap(sys._MEIPASS+"\loading.ico")
btn=CTkButton(master=app,text='Select Gif',corner_radius=20,fg_color="#C850C0",hover_color="#4158D0",border_color="#000000",border_width=2,width=150,height=50,command=select_gif_file)
btn.place(relx=0.5,rely=0.1,anchor="center")
app.mainloop()
117 changes: 117 additions & 0 deletions create_boot_animation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import argparse
import os
import tempfile
import zipfile
from PIL import Image
import gifextract

def create(source, width, height, fps, save_to):
zip=True
source_dir = ""
temp_dir = None
if os.path.isdir(source):
source_dir = source
elif os.path.isfile(source) and get_extension(source) == "gif":
temp_dir = tempfile.TemporaryDirectory()
gifextract.processImage(source, temp_dir.name,width,height)
source_dir = temp_dir.name
else:
print("Error: invalid source path: " + source)
return

images = get_images_paths(source_dir)
if len(images) <= 0:
print("Error: no images to process")
return

if not os.path.exists(save_to):
os.makedirs(save_to)

path_to_desc_file = create_desc_file(save_to, width, height, fps)

dir_for_images = save_to + "/part0"
if not os.path.exists(dir_for_images):
os.makedirs(dir_for_images)

count = 0
for img in images:
count = transform_images(img, count, width, height, dir_for_images)

with open(path_to_desc_file, "a") as f:
print("p 1 0 part0", file=f)

if zip is True:
zip_file = zipfile.ZipFile(save_to + "/bootanimation.zip", mode="w",
compression=zipfile.ZIP_STORED)

zip_file.write(path_to_desc_file,
arcname=os.path.basename(path_to_desc_file))

zip_dir(dir_for_images, zip_file)
zip_file.close()

print("Done")
return True



def get_extension(t_path):
path_parts = str.split(t_path, '.')
extension = path_parts[-1:][0]
extension = extension.lower()
return extension


def get_images_paths(t_folder):
if not os.path.isdir(t_folder):
return list()

image_extensions = ("jpg", "jpeg", "bmp", "png", "tiff")
images = list()
entries = os.listdir(t_folder)
for entry in entries:
file_path = os.path.join(t_folder, entry)
extension = get_extension(file_path)
if os.path.isfile(file_path) and extension in image_extensions:
images.append(file_path)

images.sort()
return images


def create_desc_file(t_folder, width, height, fps):
file_name = t_folder + "/desc.txt"
fd = open(file_name, mode="w+")
print("{} {} {}".format(width, height, fps), file=fd)
return file_name


def transform_images(t_img_path, t_count, width, height, save_to_path):
original_img = Image.open(t_img_path)

# Scale image
width_percent = (width / float(original_img.width))
height_size = int((float(original_img.height) * float(width_percent)))
original_img = original_img.resize((width, height_size), Image.LANCZOS)

result_image = Image.new("RGB", (width, height), "white")

width_pos = 0
height_pos = int(height / 2 - original_img.height / 2)
result_image.paste(original_img, (width_pos, height_pos))

result_img_name = "{0:0{width}}.png".format(t_count, width=5)
result_img_path = save_to_path + "/" + result_img_name
result_image.save(result_img_path)
t_count += 1
return t_count


def zip_dir(t_path, zip_file):
path_head, last_dir = os.path.split(t_path)
images = get_images_paths(t_path)
for img in images:
img_path_in_zip = last_dir + "/" + os.path.basename(img)
zip_file.write(img, arcname=img_path_in_zip,
compress_type=zipfile.ZIP_STORED)

67 changes: 67 additions & 0 deletions gifextract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from PIL import Image
import os



def analyseImage(path):
"""
Pre-process pass over the image to determine the mode (full or additive).
Necessary as assessing single frames isn't reliable. Need to know the mode
before processing all frames.
"""
im = Image.open(path)
results = {
'size': im.size,
'mode': 'full',
}

try:
while True:
if im.tile:
tile = im.tile[0]
update_region = tile[1]
update_region_dimensions = update_region[2:]
if update_region_dimensions != im.size:
results['mode'] = 'partial'
break

im.seek(im.tell() + 1)
except EOFError:
pass
return results


def processImage(path, output_folder,new_width, new_height):
"""
Iterate the GIF, extracting each frame.
"""
if not isinstance(new_width, int):
new_width=int(new_width)
if not isinstance(new_height, int):
new_height=int(new_height)
mode = analyseImage(path)['mode']
gif = Image.open(path)

# Create the output folder if it doesn't exist
if not os.path.exists(output_folder):
os.makedirs(output_folder)

for frame_number in range(gif.n_frames):
gif.seek(frame_number)
frame = gif.convert("RGBA")

adjusted_frame_number = (frame_number - 1) % gif.n_frames

resized_frame = frame.resize((new_width, new_height), Image.BOX)

new_frame = Image.new('RGBA', (new_width,new_height))

if mode == 'partial':
new_frame.paste(resized_frame)

new_frame.paste(resized_frame, (0, 0), resized_frame)

result_frame_path = os.path.join(output_folder, f"{adjusted_frame_number:05d}.png")
new_frame.save(result_frame_path, 'PNG')

gif.close()
Binary file added loading.ico
Binary file not shown.
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
customtkinter==5.2.2
Pillow==10.2.0

0 comments on commit d792308

Please sign in to comment.