import gradio as gr import numpy as np from PIL import Image import os # Convert 24-bit RGB to 16-bit RGB565 def rgb_to_rgb565(r, g, b): return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) # Convert image to RGB565 format def convert_to_rgb565(image): image = image.convert("RGB") # Ensure image is in RGB mode pixels = np.array(image) height, width, _ = pixels.shape rgb565_data = [] for y in range(height): for x in range(width): r, g, b = pixels[y, x] rgb565_data.append(rgb_to_rgb565(r, g, b)) return rgb565_data, width, height # Generate a .c file with RGB565 image data def generate_c_file(frames, width, height, output_filename="gif_frames.c"): with open(output_filename, "w") as f: f.write("#include \n\n") f.write(f"const uint16_t gif_width = {width};\n") f.write(f"const uint16_t gif_height = {height};\n\n") for i, frame in enumerate(frames): f.write(f"const uint16_t frame_{i}[] = {{\n") for j, pixel in enumerate(frame): f.write(f"0x{pixel:04X}, ") if (j + 1) % 10 == 0: f.write("\n") f.write("};\n\n") f.write(f"const uint16_t* gif_frames[{len(frames)}] = {{\n") for i in range(len(frames)): f.write(f" frame_{i},\n") f.write("};\n") # Function to process GIF and return the .c file def process_gif(gif_file): gif = Image.open(gif_file) frames = [] frame_index = 0 while True: rgb565_data, width, height = convert_to_rgb565(gif) frames.append(rgb565_data) frame_index += 1 try: gif.seek(gif.tell() + 1) # Move to next frame except EOFError: break output_filename = "/tmp/gif_frames.c" generate_c_file(frames, width, height, output_filename) return output_filename # Gradio Interface def gif_to_c_file(gif_file): output_file = process_gif(gif_file) with open(output_file, "r") as file: return file.read() iface = gr.Interface(fn=gif_to_c_file, inputs=gr.File(label="Upload GIF"), outputs="text", title="GIF to C File Converter", description="Upload a GIF to convert it into a C file with RGB565 format for use on LilyGO T-Display S3.") iface.launch()