67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
import io
|
|
import base64
|
|
import cv2
|
|
import numpy as np
|
|
|
|
def numpy_arr_to_zip_str(arr):
|
|
f = io.BytesIO()
|
|
np.savez_compressed(f, arr=arr)
|
|
return base64.b64encode(f.getvalue())
|
|
|
|
def numpy_zip_str_to_arr(zip_str):
|
|
f = io.BytesIO(base64.b64decode(zip_str))
|
|
return np.load(f)['arr'].tolist()
|
|
|
|
def read_image(content: bytes) -> np.ndarray:
|
|
"""
|
|
Image bytes to OpenCV image
|
|
|
|
:param content: Image bytes
|
|
:returns OpenCV image
|
|
:raises TypeError: If content is not bytes
|
|
:raises ValueError: If content does not represent an image
|
|
"""
|
|
if not isinstance(content, bytes):
|
|
raise TypeError(f"Expected 'content' to be bytes, received: {type(content)}")
|
|
image = cv2.imdecode(np.frombuffer(content, dtype=np.uint8), cv2.IMREAD_COLOR)
|
|
if image is None:
|
|
raise ValueError(f"Expected 'content' to be image bytes")
|
|
return image
|
|
|
|
|
|
def parse_image(img):
|
|
(img_h, img_w) = img.shape[:2]
|
|
t = 1920
|
|
w = t
|
|
h = int((img_h / img_w) * t)
|
|
img = cv2.resize(img, (w, h))
|
|
|
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
|
gray = 255 - gray
|
|
gray = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY)[1]
|
|
gray = cv2.blur(gray, (10, 5))
|
|
contours, hierarchy = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
|
|
|
|
for cnt in contours:
|
|
area = cv2.contourArea(cnt)
|
|
# if area > 150000 and area < 500000:
|
|
cv2.drawContours(img, [cnt], 0, (255, 0, 0), 2)
|
|
|
|
svg_paths = []
|
|
|
|
for cnt in contours:
|
|
if len(cnt) > 80:
|
|
svg_path = "M"
|
|
for i in range(len(cnt)):
|
|
x, y = cnt[i][0]
|
|
svg_path += f"{x} {y} "
|
|
svg_paths.append(svg_path)
|
|
|
|
return {
|
|
"width": w,
|
|
"height": h,
|
|
"paths": svg_paths,
|
|
"array": gray.tolist(),
|
|
"b64": numpy_arr_to_zip_str(gray),
|
|
}
|