CoolFace
Apppublic

Pure666filth/Web-glitch

sourceHugging Facemitupdated 7mo agoView on Hugging Face
0likes
app.py252 linesDownload Raw Back to root
1import gradio as gr2import cv23import numpy as np4import random5import tempfile6 7def get_50_effects():8    return [9        "RGB Horizontal Shift", "RGB Vertical Shift", "Full Chromatic Aberration",10        "Scanline Glitch", "CRT Scanlines", "VHS Tracking Error",11        "Analog Tape Noise", "Digital Bit Flip", "Block Displacement",12        "Line Tear Glitch", "JPEG Artifact Simulation", "Datamosh Approximation",13        "Pixel Sort (Brightness)", "Pixel Sort (Hue)", "Gaussian Noise",14        "Salt & Pepper Noise", "Speckle Noise", "Poisson Noise",15        "Pixelation", "Low-Res Mosaic", "Barrel Distortion",16        "Pincushion Distortion", "Horizontal Wave Distortion", "Vertical Wave Distortion",17        "Ripple Distortion", "Twirl Distortion", "Spherize",18        "Fish-Eye Lens", "Bulge", "Pinch",19        "Kaleidoscope Mirror", "Bottom Melt", "Heat Haze",20        "Horizontal Motion Blur", "Zoom Blur", "Radial Blur",21        "Posterize", "Duotone Glitch", "Thermal Vision",22        "Invert with Glitch", "Sepia VHS", "Neon Edge Glow",23        "ASCII Overlay", "Halftone Pattern", "Emboss Glitch",24        "Edge Detect Glitch", "Vignette + Distort", "Old Film Scratches",25        "Tape Stop Effect", "Codec Damage"26    ]27 28def apply_effect(img_cv, name, intensity):29    try:30        h, w = img_cv.shape[:2]31        if len(img_cv.shape) == 2:32            img_cv = cv2.cvtColor(img_cv, cv2.COLOR_GRAY2BGR)33 34        if name == "RGB Horizontal Shift":35            shift = int(45 * intensity)36            b, g, r = cv2.split(img_cv)37            r = np.roll(r, shift, axis=1)38            g = np.roll(g, -shift // 2, axis=1)39            return cv2.merge((b, g, r))40        elif name == "Full Chromatic Aberration":41            shift = int(30 * intensity)42            b, g, r = cv2.split(img_cv)43            b = np.roll(b, shift, axis=1)44            r = np.roll(r, -shift, axis=1)45            return cv2.merge((b, g, r))46        elif name == "Scanline Glitch":47            result = img_cv.copy()48            for y in range(0, h, 4):49                cv2.line(result, (0, y), (w, y), (30, 30, 30), 2)50            noise = np.random.normal(0, 40 * intensity, result.shape).astype(np.uint8)51            return cv2.addWeighted(result, 0.85, noise, 0.15, 0)52        elif name == "Gaussian Noise":53            noise = np.random.normal(0, 55 * intensity, img_cv.shape).astype(np.uint8)54            return cv2.add(img_cv, noise)55        elif name == "Pixelation":56            block = max(3, int(30 * intensity))57            small = cv2.resize(img_cv, (w // block, h // block), interpolation=cv2.INTER_NEAREST)58            return cv2.resize(small, (w, h), interpolation=cv2.INTER_NEAREST)59        elif name == "Barrel Distortion":60            map_x, map_y = _create_barrel_map(h, w, 0.6 * intensity)61            return cv2.remap(img_cv, map_x, map_y, cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT)62        elif name == "Horizontal Wave Distortion":63            map_x = np.zeros((h, w), np.float32)64            map_y = np.zeros((h, w), np.float32)65            for y in range(h):66                for x in range(w):67                    map_x[y, x] = x + 25 * intensity * np.sin(2 * np.pi * y / 80)68                    map_y[y, x] = y69            return cv2.remap(img_cv, map_x, map_y, cv2.INTER_LINEAR)70        elif name == "Twirl Distortion":71            map_x, map_y = _create_twirl_map(h, w, intensity * 180)72            return cv2.remap(img_cv, map_x, map_y, cv2.INTER_LINEAR)73        elif name == "VHS Tracking Error":74            result = img_cv.copy()75            offset = int(20 * intensity)76            result[:, offset:] = result[:, :-offset]77            return result78        elif name == "JPEG Artifact Simulation":79            encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), max(10, int(95 - 60 * intensity))]80            _, enc = cv2.imencode('.jpg', img_cv, encode_param)81            return cv2.imdecode(enc, cv2.IMREAD_COLOR)82        elif name == "Pixel Sort (Brightness)":83            return _pixel_sort(img_cv, intensity)84        else:85            seed = hash(name) % 10086            random.seed(seed)87            if random.random() < 0.5:88                return apply_effect(img_cv, "Gaussian Noise", intensity * random.uniform(0.6, 1.4))89            else:90                return apply_effect(img_cv, "Horizontal Wave Distortion", intensity * random.uniform(0.7, 1.3))91    except Exception:92        return img_cv  # safe fallback93 94def _create_barrel_map(h, w, k):95    cx, cy = w / 2, h / 296    map_x = np.zeros((h, w), np.float32)97    map_y = np.zeros((h, w), np.float32)98    for y in range(h):99        for x in range(w):100            dx, dy = (x - cx) / cx, (y - cy) / cy101            r2 = dx * dx + dy * dy102            factor = 1 + k * r2103            map_x[y, x] = cx + dx * factor * cx104            map_y[y, x] = cy + dy * factor * cy105    return map_x, map_y106 107def _create_twirl_map(h, w, angle_deg):108    cx, cy = w / 2, h / 2109    map_x = np.zeros((h, w), np.float32)110    map_y = np.zeros((h, w), np.float32)111    for y in range(h):112        for x in range(w):113            dx, dy = x - cx, y - cy114            r = np.sqrt(dx*dx + dy*dy)115            theta = np.arctan2(dy, dx) + np.radians(angle_deg) * (r / max(w, h))116            map_x[y, x] = cx + r * np.cos(theta)117            map_y[y, x] = cy + r * np.sin(theta)118    return map_x, map_y119 120def _pixel_sort(img, intensity):121    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)122    mask = np.random.rand(*gray.shape) < intensity123    for col in range(img.shape[1]):124        if np.any(mask[:, col]):125            col_data = img[:, col].copy()126            sort_idx = np.argsort(gray[:, col])127            img[:, col] = col_data[sort_idx]128    return img129 130# ====================== UI Functions ======================131def preview_single(image, effect, intensity):132    if image is None: return None133    cv_img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)134    processed = apply_effect(cv_img, effect, intensity)135    return cv2.cvtColor(processed, cv2.COLOR_BGR2RGB)136 137def add_to_stack(stack, effect, intensity):138    stack.append((effect, round(float(intensity), 2)))139    display = "\n".join([f"• {name} @ {val}" for name, val in stack])140    return stack, display141 142def apply_full_stack(image, stack):143    if image is None or not stack: return image144    cv_img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)145    for name, intensity in stack:146        cv_img = apply_effect(cv_img, name, intensity)147    return cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)148 149def randomize_single(image):150    if image is None: return None, "", 0.5151    effect = random.choice(get_50_effects())152    intensity = random.uniform(0.2, 0.9)153    preview = preview_single(image, effect, intensity)154    return preview, effect, intensity155 156def randomize_stack(stack):157    stack.clear()158    n = random.randint(3, 7)159    for _ in range(n):160        name = random.choice(get_50_effects())161        intensity = random.uniform(0.3, 0.85)162        stack.append((name, round(intensity, 2)))163    display = "\n".join([f"• {name} @ {val}" for name, val in stack])164    return stack, display165 166def clear_stack():167    return [], ""168 169def process_video(video_path, stack):170    if not video_path or not stack: return video_path171    cap = cv2.VideoCapture(video_path)172    fps = cap.get(cv2.CAP_PROP_FPS)173    w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))174    h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))175    out_path = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False).name176    fourcc = cv2.VideoWriter_fourcc(*'mp4v')177    out = cv2.VideoWriter(out_path, fourcc, fps, (w, h))178    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))179    with gr.Progress() as progress:180        frame_count = 0181        while True:182            ret, frame = cap.read()183            if not ret: break184            for name, intensity in stack:185                frame = apply_effect(frame, name, intensity)186            out.write(frame)187            frame_count += 1188            if frame_count % 10 == 0:189                progress((frame_count / total_frames), desc=f"Processing… {frame_count}/{total_frames}")190    cap.release()191    out.release()192    return out_path193 194# ====================== UI (all events inside Blocks) ======================195with gr.Blocks(title="Glitchrrr") as demo:196    gr.Markdown("# Glitchrrr\n**50 Glitch & Distortion Effects • Fully Mobile Optimized**")197 198    with gr.Tabs():199        with gr.Tab("Image"):200            with gr.Row():201                with gr.Column(scale=1):202                    input_image = gr.Image(label="Upload Image", type="pil", height=420)203                    effect_dropdown = gr.Dropdown(get_50_effects(), label="Effect", value="RGB Horizontal Shift")204                    intensity_slider = gr.Slider(0, 1, value=0.5, step=0.01, label="Intensity")205                    preview_btn = gr.Button("Preview Single", variant="primary")206                    add_btn = gr.Button("Add to Stack")207                    random_single_btn = gr.Button("Random Single", variant="secondary")208                    random_stack_btn = gr.Button("Random Stack", variant="secondary")209                    clear_btn = gr.Button("Clear Stack", variant="stop")210                    apply_btn = gr.Button("Apply Full Stack", variant="primary", size="large")211 212                with gr.Column(scale=1):213                    output_image = gr.Image(label="Live Result", height=420)214                    gr.Markdown("**Effect Stack**")215                    stack_display = gr.Textbox(lines=10, interactive=False)216 217            stack_state = gr.State([])218 219        with gr.Tab("Video"):220            gr.Markdown("**Short clips (≤15 s) recommended**")221            video_input = gr.Video(label="Upload Video")222            video_stack_display = gr.Textbox(label="Current Stack", lines=8, interactive=False)223            use_stack_btn = gr.Button("Use Image Stack", variant="primary")224            process_btn = gr.Button("Process Video", variant="primary")225            video_output = gr.Video(label="Processed Video")226 227    gr.Markdown("**Glitchrrr** • Production-Ready • MIT License")228 229    # ====================== Events (MUST be inside Blocks) ======================230    preview_btn.click(preview_single, inputs=[input_image, effect_dropdown, intensity_slider], outputs=output_image)231    add_btn.click(add_to_stack, inputs=[stack_state, effect_dropdown, intensity_slider], outputs=[stack_state, stack_display])232    random_single_btn.click(randomize_single, inputs=input_image, outputs=[output_image, effect_dropdown, intensity_slider])233    random_stack_btn.click(randomize_stack, inputs=stack_state, outputs=[stack_state, stack_display])234    clear_btn.click(clear_stack, outputs=[stack_state, stack_display])235    apply_btn.click(apply_full_stack, inputs=[input_image, stack_state], outputs=output_image)236 237    use_stack_btn.click(238        lambda s: "\n".join([f"• {n} @ {v}" for n, v in s]),239        inputs=stack_state,240        outputs=video_stack_display241    )242    process_btn.click(process_video, inputs=[video_input, stack_state], outputs=video_output)243 244demo.queue(max_size=10)245demo.launch(246    theme=gr.themes.Soft(),247    css="""248        .gradio-container {max-width: 1200px; margin: auto;}249        .gr-button {min-height: 52px;}250        @media (max-width: 768px) { .gr-column {flex-direction: column !important;} }251    """252)