66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
"""Image and timestamp helpers used by the Ollama/OpenAI request pipeline."""
|
|
import base64
|
|
import io
|
|
import time
|
|
from datetime import datetime, timezone
|
|
|
|
from PIL import Image
|
|
|
|
|
|
def iso8601_ns():
|
|
ns = time.time_ns()
|
|
sec, ns_rem = divmod(ns, 1_000_000_000)
|
|
dt = datetime.fromtimestamp(sec, tz=timezone.utc)
|
|
return (
|
|
f"{dt.year:04d}-{dt.month:02d}-{dt.day:02d}T"
|
|
f"{dt.hour:02d}:{dt.minute:02d}:{dt.second:02d}."
|
|
f"{ns_rem:09d}Z"
|
|
)
|
|
|
|
|
|
def is_base64(image_string):
|
|
try:
|
|
if isinstance(image_string, str) and base64.b64encode(base64.b64decode(image_string)) == image_string.encode():
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
def resize_image_if_needed(image_data):
|
|
try:
|
|
# Check if already data-url
|
|
if image_data.startswith("data:"):
|
|
try:
|
|
header, image_data = image_data.split(",", 1)
|
|
except ValueError:
|
|
pass
|
|
# Decode the base64 image data
|
|
image_bytes = base64.b64decode(image_data)
|
|
with Image.open(io.BytesIO(image_bytes)) as image:
|
|
if image.mode not in ("RGB", "L"):
|
|
image = image.convert("RGB")
|
|
|
|
# Get current size
|
|
width, height = image.size
|
|
|
|
# Calculate the new dimensions while maintaining aspect ratio
|
|
if width > 512 or height > 512:
|
|
aspect_ratio = width / height
|
|
if aspect_ratio > 1: # Width is larger
|
|
new_width = 512
|
|
new_height = int(512 / aspect_ratio)
|
|
else: # Height is larger
|
|
new_height = 512
|
|
new_width = int(512 * aspect_ratio)
|
|
|
|
image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)
|
|
|
|
# Encode the resized image back to base64
|
|
buffered = io.BytesIO()
|
|
image.save(buffered, format="PNG")
|
|
resized_image_data = base64.b64encode(buffered.getvalue()).decode("utf-8")
|
|
return resized_image_data
|
|
|
|
except Exception as e:
|
|
print(f"Error processing image: {e}")
|
|
return None
|