| import base64 | |
| from PIL import Image | |
| import requests | |
| from io import BytesIO | |
| import numpy as np | |
| def is_placeholder_image(image: Image.Image) -> bool: | |
| img_array = np.array(image) | |
| if len(img_array.shape) != 3: | |
| return True | |
| height, width = img_array.shape[:2] | |
| gray = np.mean(img_array, axis=2) | |
| unique_colors = len(np.unique(gray)) | |
| if unique_colors < 10: | |
| return True | |
| black_white_ratio = np.sum((gray < 20) | (gray > 235)) / (height * width) | |
| if black_white_ratio > 0.8: | |
| return True | |
| std_dev = np.std(gray) | |
| if std_dev < 15: | |
| return True | |
| sample_size = min(100, height // 10, width // 10) | |
| if sample_size < 2: | |
| return False | |
| step_h = height // sample_size | |
| step_w = width // sample_size | |
| grid_pattern = True | |
| for i in range(0, height - step_h, step_h): | |
| for j in range(0, width - step_w, step_w): | |
| block = gray[i:i+step_h, j:j+step_w] | |
| block_std = np.std(block) | |
| if block_std > 30: | |
| grid_pattern = False | |
| break | |
| if not grid_pattern: | |
| break | |
| if grid_pattern and black_white_ratio > 0.5: | |
| return True | |
| return False | |
| def load_image_from_url(url_or_base64: str) -> Image.Image: | |
| try: | |
| if url_or_base64.startswith("data:image"): | |
| header, encoded = url_or_base64.split(",", 1) | |
| image_data = base64.b64decode(encoded) | |
| return Image.open(BytesIO(image_data)).convert("RGB") | |
| else: | |
| response = requests.get(url_or_base64, timeout=10) | |
| response.raise_for_status() | |
| return Image.open(BytesIO(response.content)).convert("RGB") | |
| except Exception as e: | |
| raise ValueError(f"Failed to load image: {str(e)}") | |
| def filter_valid_images(images: list) -> list: | |
| valid_images = [] | |
| for img in images: | |
| if not img or not isinstance(img, str) or img.strip() in ["", "string", "null", "undefined"]: | |
| continue | |
| try: | |
| pil_image = load_image_from_url(img) | |
| if not is_placeholder_image(pil_image): | |
| valid_images.append(pil_image) | |
| else: | |
| print(f"[IMAGE FILTER] Ignoring placeholder/empty image") | |
| except Exception as e: | |
| print(f"[IMAGE FILTER] Warning: Failed to load image: {e}, skipping") | |
| continue | |
| return valid_images | |