#! /usr/local/bin/python3 from io import BytesIO from numpy import asarray from PIL import Image from redis import Redis import base64 import json import os import potrace import re import time color = 65280 environ = os.environ host = environ['DB_HOST'] if 'DB_HOST' in os.environ else "localhost" port = environ['DB_PORT'] if 'DB_PORT' in os.environ else 6379 r = Redis(host=host, port=port) def convertImg(src, image_path="/tmp/"): base64_data = re.sub('^data:image/.+;base64,', '', src) byte_data = base64.b64decode(base64_data) image_data = BytesIO(byte_data) img = Image.open(image_data).convert("1") return img # Read results from redis data = r.lpop('image-convert') while data : try: item = json.loads(data) image_data = item["image_data"] text = item["text"] hash_name = item["hash_name"] # Vectorize the image image = convertImg( image_data ) bmp = potrace.Bitmap( asarray( image ) ) # Trace the bitmap to a path path = bmp.trace(turdsize=16,alphamax=0.0, opticurve=0, opttolerance=1.0) # Record the min/max coordinates and a list of points min_x = 0 min_y = 0 max_x = -9999 max_y = -9999 pl = [] pl_index = 0 odd_indices = [] def plappend( point ): global pl, pl_index, odd_indices, min_x, min_y, max_x, max_y pl.append(point) pl_index += 1 suspect = False if point[0] <= min_x : min_x = point[0] suspect = True if point[0] >= max_x : max_x = point[0] suspect = True if point[1] <= min_y : min_y = point[1] suspect = True if point[1] >= max_y : max_y = point[1] suspect = True if suspect == True: odd_indices.append(pl_index) return True return False for curve in path: start = curve.start_point plappend([int(start[0]),int(start[1]),0]) plappend([int(start[0]),int(start[1]),color]) for segment in curve: end_point_x, end_point_y = segment.end_point if segment.is_corner: c_x, c_y = segment.c plappend([int(c_x),int(c_y),color]) pass # else: c1_x, c1_y = segment.c1 x, y = segment.c2 plappend([int(x),int(y),color]) plappend([int(c1_x),int(c1_y),color]) # plappend([int(start[0]),int(start[1]),0]) # Run the border detection def isBorder( pt ): result = [] # calculate the distance to min/max min_x_dst = abs(min_x - pt[0]) max_x_dst = abs(max_x - pt[0]) min_y_dst = abs(min_y - pt[1]) max_y_dst = abs(max_y - pt[1]) if min_x_dst <= 1 : result.append("min_x") if max_x_dst <= 1 : result.append("max_x") if min_y_dst <= 1 : result.append("min_y") if max_y_dst <= 1 : result.append("max_y") return result deleteList = [] for i in range(len(odd_indices) - 1) : ind = odd_indices[i] pt = pl[ind] nextpt = pl[ind+1] # Early skip black points if 0 == pt[2] or 0 == nextpt[2]: continue pt_is_bord = isBorder(pt) nextpt_is_bord = isBorder(nextpt) if 0 == len(pt_is_bord) or 0 == len(nextpt_is_bord): continue #print( "{} and {} are border.".format(pt,nextpt)) deleteList.append(ind) deleteList.append(ind+1) deleteList = sorted(set(deleteList), reverse=True) for i in deleteList: pl[i] = [pl[i][0],pl[i][1],0] item["points_list"] = pl item["created_at"] = time.time() r.hset("images",hash_name, json.dumps(item)) print("Handled image {}".format(hash_name)) data = r.lpop('image-convert') except Exception as e: print("woops",e) break