|
|
|
|
|
|
|
|
import os |
|
|
import cv2 |
|
|
import numpy as np |
|
|
from sklearn.cluster import KMeans |
|
|
import urllib.request |
|
|
import ssl |
|
|
from supabase import create_client, Client |
|
|
from dotenv import load_dotenv |
|
|
|
|
|
|
|
|
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
|
|
load_dotenv(dotenv_path=os.path.join(ROOT_DIR, '.env')) |
|
|
|
|
|
def get_supabase_client() -> Client: |
|
|
""" |
|
|
Creates and returns a Supabase client. |
|
|
Raises ValueError if credentials are not set in the environment. |
|
|
""" |
|
|
try: |
|
|
url = os.environ.get("SUPABASE_URL") |
|
|
key = os.environ.get("SUPABASE_SERVICE_KEY") |
|
|
if not url or not key: |
|
|
raise ValueError("Supabase credentials (URL or Service Key) are not set.") |
|
|
return create_client(url, key) |
|
|
except Exception as e: |
|
|
print(f"π΄ FATAL: Could not create Supabase client: {e}") |
|
|
raise |
|
|
|
|
|
def extract_colors_from_url(image_url: str, num_colors=4) -> list: |
|
|
""" |
|
|
Downloads an image from a URL and returns the top N dominant colors in Hex format. |
|
|
Requires: opencv-python-headless, scikit-learn, numpy |
|
|
""" |
|
|
try: |
|
|
print(f"π¨ Extracting colors from: {image_url}") |
|
|
|
|
|
|
|
|
context = ssl._create_unverified_context() |
|
|
|
|
|
|
|
|
with urllib.request.urlopen(image_url, context=context) as req: |
|
|
arr = np.asarray(bytearray(req.read()), dtype=np.uint8) |
|
|
img = cv2.imdecode(arr, -1) |
|
|
|
|
|
if img is None: |
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
if img.shape[2] == 4: |
|
|
img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR) |
|
|
|
|
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
|
|
img = cv2.resize(img, (100, 100), interpolation=cv2.INTER_AREA) |
|
|
|
|
|
|
|
|
img = img.reshape((img.shape[0] * img.shape[1], 3)) |
|
|
|
|
|
|
|
|
kmeans = KMeans(n_clusters=num_colors, n_init='auto') |
|
|
kmeans.fit(img) |
|
|
colors = kmeans.cluster_centers_ |
|
|
|
|
|
|
|
|
hex_colors = [] |
|
|
for color in colors: |
|
|
hex_code = '#{:02x}{:02x}{:02x}'.format(int(color[0]), int(color[1]), int(color[2])) |
|
|
hex_colors.append(hex_code) |
|
|
|
|
|
return hex_colors |
|
|
|
|
|
except Exception as e: |
|
|
print(f"β οΈ Error extracting colors: {str(e)}") |
|
|
|
|
|
return ["#000000", "#808080"] |