import cv2 import numpy as np import gradio as gr import time # ---------------------------- # Sketch Conversion Functions # ---------------------------- def dodgeV2(image, mask): """Helper function for pencil sketch effect""" return cv2.divide(image, 255 - mask, scale=256) def pencil_sketch(img, scale=256, blur_value=21, texture=False): """Convert image to realistic pencil sketch""" # Convert to grayscale gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Invert image inv_gray = 255 - gray_img # Apply Gaussian blur blur_img = cv2.GaussianBlur(inv_gray, (blur_value, blur_value), 0) # Blend using dodge technique sketch = dodgeV2(gray_img, blur_img) # Optional: Add paper texture if texture: h, w = sketch.shape paper = np.random.normal(loc=200, scale=30, size=(h, w)).astype(np.uint8) sketch = cv2.multiply(sketch, paper, scale=1/255) return sketch # ---------------------------- # Animation Function # ---------------------------- def animate_sketch(image, scale=256, blur=21, texture=False, delay=0.01): """Simulate hand-drawn line-by-line animation""" img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) sketch = pencil_sketch(img, scale=scale, blur_value=blur, texture=texture) # Create blank canvas h, w = sketch.shape canvas = np.ones((h, w), dtype=np.uint8) * 255 frames = [] for i in range(h): canvas[i] = sketch[i] # Draw line by line frame_rgb = cv2.cvtColor(canvas, cv2.COLOR_GRAY2RGB) frames.append(frame_rgb) return frames # ---------------------------- # Gradio Interface # ---------------------------- def gradio_sketch(image, scale, blur, texture): frames = animate_sketch(image, scale, blur, texture) return frames # Gradio will display as GIF automatically # Gradio UI title = "🎨 Realistic Pencil Sketch Animation" description = """ Upload any image and watch it transform into a realistic pencil sketch with hand-drawn animation! You can adjust: - Scale: pencil intensity - Blur: smoothness of strokes - Texture: add paper texture """ iface = gr.Interface( fn=gradio_sketch, inputs=[ gr.Image(type="pil", label="Upload Image"), gr.Slider(64, 512, value=256, step=1, label="Scale"), gr.Slider(1, 51, value=21, step=2, label="Blur"), gr.Checkbox(label="Add Paper Texture?") ], outputs=gr.Gallery(label="Animated Sketch"), title=title, description=description, allow_flagging="never", ) if __name__ == "__main__": iface.launch()