Spaces:
Runtime error
Runtime error
""" | |
Image process utils. Used to verify, convert and store Images. | |
@file: img_utils.py | |
@author: Konie | |
@update: 2024-03-23 | |
""" | |
import base64 | |
from io import BytesIO | |
from fastapi import UploadFile | |
from PIL import Image | |
import starlette | |
import requests | |
import numpy as np | |
async def convert_image(image_path: str, image_format: str = 'png') -> BytesIO: | |
""" | |
Convert image to another format | |
Args: | |
image_path (str): Image path | |
image_format (str): Image format | |
Returns: | |
BytesIO: Image bytes | |
""" | |
try: | |
img = Image.open(image_path) | |
image_bytes = BytesIO() | |
img.save(image_bytes, format=image_format.upper()) | |
image_bytes.seek(0) | |
except Exception as e: | |
print(e) | |
return | |
return image_bytes.getvalue() | |
def upload2base64(image: UploadFile) -> str | None: | |
""" | |
Convert UploadFile obj to base64 string | |
Args: | |
image (UploadFile): UploadFile obj | |
Returns: | |
str: base64 string, None for None | |
""" | |
if image is None: | |
return None | |
image_bytes = image.file.read() | |
image_base64 = base64.b64encode(image_bytes).decode("utf-8") | |
return image_base64 | |
def narray_to_base64img(narray: np.ndarray) -> str | None: | |
""" | |
Convert numpy array to base64 image string. | |
Args: | |
narray: numpy array | |
Returns: | |
base64 image string | |
""" | |
if narray is None: | |
return None | |
img = Image.fromarray(narray) | |
output_buffer = BytesIO() | |
img.save(output_buffer, format='PNG') | |
byte_data = output_buffer.getvalue() | |
base64_str = base64.b64encode(byte_data).decode('utf-8') | |
return base64_str | |
def narray_to_bytesimg(narray) -> bytes | None: | |
""" | |
Convert numpy array to bytes image. | |
Args: | |
narray: numpy array | |
Returns: | |
bytes image | |
""" | |
if narray is None: | |
return None | |
img = Image.fromarray(narray) | |
output_buffer = BytesIO() | |
img.save(output_buffer, format='PNG') | |
byte_data = output_buffer.getvalue() | |
return byte_data | |
def read_input_image(input_image: UploadFile | str | None) -> np.ndarray | None: | |
""" | |
Read input image from UploadFile or base64 string. | |
Args: | |
input_image: UploadFile, or base64 image string, or None | |
Returns: | |
numpy array of image | |
""" | |
headers = { | |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0' | |
} | |
if isinstance(input_image, str): | |
if input_image is None or input_image in ('', 'None', 'null', 'string', 'none'): | |
return None | |
if input_image.startswith("http"): | |
try: | |
response = requests.get(input_image, headers=headers, timeout=20) | |
input_image_bytes = response.content | |
except Exception: | |
return None | |
else: | |
if input_image.startswith('data:image'): | |
input_image = input_image.split(sep=',', maxsplit=1)[1] | |
input_image_bytes = base64.b64decode(input_image) | |
if isinstance(input_image, (UploadFile, starlette.datastructures.UploadFile)): | |
input_image_bytes = input_image.file.read() | |
pil_image = Image.open(BytesIO(input_image_bytes)) | |
image = np.array(pil_image) | |
if image.ndim == 2: | |
image = np.stack((image, image, image), axis=-1) | |
return image | |
def base64_to_stream(image: str) -> UploadFile | None: | |
""" | |
Convert base64 image string to UploadFile. | |
Args: | |
image: base64 image string | |
Returns: | |
UploadFile or None | |
""" | |
if image in ['', None, 'None', 'none', 'string', 'null']: | |
return None | |
if image.startswith('http'): | |
return get_check_image(url=image) | |
if image.startswith('data:image'): | |
image = image.split(sep=',', maxsplit=1)[1] | |
image_bytes = base64.b64decode(image) | |
byte_stream = BytesIO() | |
byte_stream.write(image_bytes) | |
byte_stream.seek(0) | |
return UploadFile(file=byte_stream) | |
def get_check_image(url: str) -> UploadFile | None: | |
""" | |
Get image from url and check if it's valid. | |
Args: | |
url: image url | |
Returns: | |
UploadFile or None | |
""" | |
if url == '': | |
return None | |
headers = { | |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' | |
} | |
try: | |
response = requests.get(url, headers=headers, timeout=10) | |
binary_image = response.content | |
except Exception: | |
return None | |
try: | |
buffer = BytesIO(binary_image) | |
Image.open(buffer) # This validates the image | |
except Exception: | |
return None | |
byte_stream = BytesIO() | |
byte_stream.write(binary_image) | |
byte_stream.seek(0) | |
return UploadFile(file=byte_stream) | |
def bytes_image_to_io(binary_image: bytes) -> BytesIO | None: | |
""" | |
Convert bytes image to BytesIO. | |
Args: | |
binary_image: bytes image | |
Returns: | |
BytesIO or None | |
""" | |
try: | |
buffer = BytesIO(binary_image) | |
Image.open(buffer) | |
except Exception: | |
return None | |
byte_stream = BytesIO() | |
byte_stream.write(binary_image) | |
byte_stream.seek(0) | |
return byte_stream | |
def bytes_to_base64img(byte_data: bytes) -> str | None: | |
""" | |
Convert bytes image to base64 image string. | |
Args: | |
byte_data: bytes image | |
Returns: | |
base64 image string or None | |
""" | |
if byte_data is None: | |
return None | |
base64_str = base64.b64encode(byte_data).decode('utf-8') | |
return base64_str | |
def base64_to_bytesimg(base64_str: str) -> bytes | None: | |
""" | |
Convert base64 image string to bytes image. | |
Args: | |
base64_str: base64 image string | |
Returns: | |
bytes image or None | |
""" | |
if base64_str == '': | |
return None | |
bytes_image = base64.b64decode(base64_str) | |
return bytes_image | |
def base64_to_narray(base64_str: str) -> np.ndarray | None: | |
""" | |
Convert base64 image string to numpy array. | |
Args: | |
base64_str: base64 image string | |
Returns: | |
numpy array or None | |
""" | |
if base64_str == '': | |
return None | |
bytes_image = base64.b64decode(base64_str) | |
image = np.frombuffer(bytes_image, np.uint8) | |
return image | |