load_image add url loading

This commit is contained in:
Alexander G. Morano
2025-01-30 21:32:56 -05:00
parent d480ac4f8a
commit 7a880d5fbd
4 changed files with 64 additions and 48 deletions
+3
View File
@@ -96,6 +96,9 @@ You can colorize nodes via their `title` or `body`. This can be done to the node
## UPDATES
**2024/01/30** @1.2.62:
* `QUEUE` nodes can do URL loading of images
**2024/01/08** @1.2.61:
* living in the stupidest timeline where case-sensitivty matters for URLS in chrome...
* fixed stylesheet reference in help
+28 -30
View File
@@ -257,36 +257,36 @@ class QueueBaseNode(JOVBaseNode):
continue
data = [line]
if not line.lower().startswith("http"):
# <directory>;*.png;*.gif;*.jpg
base_path_str, tail = os.path.split(line)
filters = [p.strip() for p in tail.split(';')]
# <directory>;*.png;*.gif;*.jpg
base_path_str, tail = os.path.split(line)
filters = [p.strip() for p in tail.split(';')]
base_path = Path(base_path_str)
if base_path.is_absolute():
search_dir = base_path if base_path.is_dir() else base_path.parent
else:
search_dir = (ROOT / base_path).resolve()
base_path = Path(base_path_str)
if base_path.is_absolute():
search_dir = base_path if base_path.is_dir() else base_path.parent
else:
search_dir = (ROOT / base_path).resolve()
# Check if the base directory exists
if search_dir.exists():
if search_dir.is_dir():
new_data = []
filters = filters if len(filters) > 0 and isinstance(filters[0], str) else IMAGE_FORMATS
for pattern in filters:
found = glob.glob(str(search_dir / pattern), recursive=recurse)
new_data.extend([str(Path(f).resolve()) for f in found if Path(f).is_file()])
if len(new_data):
data = new_data
elif search_dir.is_file():
path = str(search_dir.resolve())
if path.lower().endswith('.txt'):
with open(path, 'r', encoding='utf-8') as f:
data = f.read().split('\n')
else:
data = [path]
elif len(results := glob.glob(str(search_dir))) > 0:
data = [x.replace('\\', '/') for x in results]
# Check if the base directory exists
if search_dir.exists():
if search_dir.is_dir():
new_data = []
filters = filters if len(filters) > 0 and isinstance(filters[0], str) else IMAGE_FORMATS
for pattern in filters:
found = glob.glob(str(search_dir / pattern), recursive=recurse)
new_data.extend([str(Path(f).resolve()) for f in found if Path(f).is_file()])
if len(new_data):
data = new_data
elif search_dir.is_file():
path = str(search_dir.resolve())
if path.lower().endswith('.txt'):
with open(path, 'r', encoding='utf-8') as f:
data = f.read().split('\n')
else:
data = [path]
elif len(results := glob.glob(str(search_dir))) > 0:
data = [x.replace('\\', '/') for x in results]
if len(data):
ret = []
@@ -303,8 +303,6 @@ class QueueBaseNode(JOVBaseNode):
if (val := self.__last_q_value.get(q_data, None)) is not None:
return val
if isinstance(q_data, (str,)):
if not os.path.isfile(q_data):
return q_data
_, ext = os.path.splitext(q_data)
if ext in IMAGE_FORMATS:
data = image_load(q_data)[0]
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "jovimetrix"
description = "Integrates Webcam, MIDI, Spout and GLSL shader support. Animation via tick. Parameter manipulation with wave generator. Math operations with Unary and Binary support. Value conversion for all major types (int, string, list, dict, Image, Mask). Shape mask generation, image stacking and channel ops, batch splitting, merging and randomizing, load images and video from anywhere, dynamic bus routing with a single node, export support for GIPHY, save output anywhere! flatten, crop, transform; check colorblindness, make stereogram or stereoscopic images, or liner interpolate values and more."
version = "1.2.61"
version = "1.2.62"
license = { file = "LICENSE" }
dependencies = [
"aenum",
+32 -17
View File
@@ -10,6 +10,7 @@ import io
from io import BytesIO
import math
import base64
import requests
from enum import Enum
from typing import List, Tuple, Union
@@ -365,13 +366,12 @@ def image_lerp(imageA: TYPE_IMAGE, imageB:TYPE_IMAGE, mask:TYPE_IMAGE=None,
return np.clip(imageA, 0, 255)
def image_load(url: str) -> Tuple[TYPE_IMAGE, TYPE_IMAGE]:
try:
img = cv2.imread(url, cv2.IMREAD_UNCHANGED)
if img is None:
raise ValueError(f"{url} could not be loaded.")
if url.lower().startswith("http"):
response = requests.get(url, stream=True)
response.raise_for_status()
img_array = np.asarray(bytearray(response.content), dtype=np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_UNCHANGED)
img = image_normalize(img)
# logger.debug(f"load image {url}: {img.ndim} {img.shape}")
if img.ndim == 3:
if img.shape[2] == 4:
img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGRA)
@@ -379,18 +379,33 @@ def image_load(url: str) -> Tuple[TYPE_IMAGE, TYPE_IMAGE]:
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
elif img.ndim < 3:
img = np.expand_dims(img, -1)
except Exception:
logger.debug(f"load image fallback to PIL {url}")
else:
try:
img = Image.open(url)
img = ImageOps.exif_transpose(img)
img = np.array(img)
if img.dtype != np.uint8:
img = np.clip(np.array(img * 255), 0, 255).astype(dtype=np.uint8)
except Exception as e:
logger.error(str(e))
raise Exception(f"Error loading image: {e}")
img = cv2.imread(url, cv2.IMREAD_UNCHANGED)
if img is None:
raise ValueError(f"{url} could not be loaded.")
img = image_normalize(img)
# logger.debug(f"load image {url}: {img.ndim} {img.shape}")
if img.ndim == 3:
if img.shape[2] == 4:
img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGRA)
else:
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
elif img.ndim < 3:
img = np.expand_dims(img, -1)
except Exception:
logger.debug(f"load image fallback to PIL {url}")
try:
img = Image.open(url)
img = ImageOps.exif_transpose(img)
img = np.array(img)
if img.dtype != np.uint8:
img = np.clip(np.array(img * 255), 0, 255).astype(dtype=np.uint8)
except Exception as e:
# logger.error(str(e))
raise Exception(f"Error loading image: {e}")
if img is None:
raise Exception(f"No file found at {url}")