Spaces:
Running
Running
Download image_utils.py from FajarHidaa/WeatherData: direct link, hf CLI and curl.
- Browser
- Download file 1.54 kB
-
https://huggingface.co/spaces/FajarHidaa/WeatherData/resolve/main/image_utils.py
- Command line
-
hf download hf://spaces/FajarHidaa/WeatherData/image_utils.py
-
curl -L -o image_utils.py https://huggingface.co/spaces/FajarHidaa/WeatherData/resolve/main/image_utils.py
1.54 kB
| import base64 | |
| import io | |
| import logging | |
| from typing import Optional, Tuple | |
| from PIL import Image, ImageOps | |
| logger = logging.getLogger(__name__) | |
| MAX_SIDE = 768 # sisi terpanjang setelah resize | |
| JPEG_QUALITIES = (72, 60, 50) | |
| MAX_OUTPUT_BYTES = 200_000 | |
| MAX_PIXELS = 40_000_000 # tolak gambar raksasa (decompression bomb) | |
| Image.MAX_IMAGE_PIXELS = MAX_PIXELS | |
| def compress_image_to_data_url(path: Optional[str]) -> Tuple[Optional[str], str]: | |
| """Return (data_url, error). Semua di memori; tidak ada file baru ditulis.""" | |
| if not path: | |
| return None, "" | |
| try: | |
| with Image.open(path) as src: | |
| if src.width * src.height > MAX_PIXELS: | |
| return None, "Resolusi foto terlalu besar." | |
| src.draft("RGB", (MAX_SIDE * 2, MAX_SIDE * 2)) # percepat decode JPEG | |
| img = ImageOps.exif_transpose(src) # perbaiki rotasi HP | |
| img = img.convert("RGB") | |
| img.thumbnail((MAX_SIDE, MAX_SIDE), Image.Resampling.LANCZOS) | |
| data = b"" | |
| for q in JPEG_QUALITIES: | |
| buf = io.BytesIO() | |
| img.save(buf, "JPEG", quality=q, optimize=True) # EXIF/GPS tidak ikut | |
| data = buf.getvalue() | |
| if len(data) <= MAX_OUTPUT_BYTES: | |
| break | |
| b64 = base64.b64encode(data).decode("ascii") | |
| return f"data:image/jpeg;base64,{b64}", "" | |
| except Exception as e: | |
| logger.warning(f"Image compress failed: {e}") | |
| return None, "Foto tidak dapat diproses." |