文档服务地址:http://47.92.0.57:3000/ 周报索引地址:http://47.92.0.57:3000/s/NruNXRYmV

Commit 3b451a8a by convivae

图片后端新增下载zip的接口

parent 57ebb542
......@@ -158,18 +158,38 @@ def get_img_point_lists(relation_id):
return point_lists
# 根据relationId获取原始图片的属性
def get_img_type(relation_id):
image_name = get_img_name(relation_id)
img_dict = {
'jpeg': 'image/jpeg',
'jpg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif'
}
img_type = image_name.split('.')[-1].lower()
mine = img_dict[img_type]
return img_type, mine
# 根据relationId获取原始图片对象
def export_original_img(relation_id):
def export_original_img_bytes(relation_id):
try:
image_name = get_img_name(relation_id)
return fileDownload.download(image_name)
img_dir = fileDownload.get_image_dir(image_name)
with open(img_dir, 'rb') as f:
a = f.read()
return io.BytesIO(a)
except Exception as e:
traceback.print_exc()
return Result(0, repr(e), {})
# 根据relationId获取图片json对象
def export_img_json(relation_id):
def export_img_json_bytes(relation_id):
try:
ret = {'version': '3.10.0', 'flags': {}}
obj = Image.objects(relationId=relation_id).first()
......@@ -208,18 +228,18 @@ def export_img_json(relation_id):
ret['imageHeight'] = img_size[1]
ret['imageWidth'] = img_size[0]
json_io = io.BytesIO()
img_json = json.dumps(ret, ensure_ascii=False, indent=4)
response = make_response(img_json)
response.headers["Content-Disposition"] = "p_w_upload; filename={}.json".format(image_name.split('.')[0])
json_io.write(img_json.encode())
return img_json, json_io
return response
except Exception as e:
traceback.print_exc()
return Result(0, repr(e), {})
# 根据relationId获取标注图片对象
def export_label_img(relation_id):
def export_label_img_bytes(relation_id):
try:
# 生成图片
image_name = get_img_name(relation_id)
......@@ -238,18 +258,9 @@ def export_label_img(relation_id):
draw.polygon(p, fill=c)
# 发送图片
img_dict = {
'jpeg': 'image/jpeg',
'jpg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif'
}
img_type = image_name.split('.')[-1].lower()
# 这里只测试了 jpg 图像(数据库中只有这个,可能发布的人比较喜欢这个格式吧。。)
# 可能存在问题,等待后续测试
mine = img_dict[img_type]
_, mine = get_img_type(relation_id)
if mine == 'image/jpeg':
img = img.convert('RGB')
......@@ -257,12 +268,7 @@ def export_label_img(relation_id):
img.save(img_io, mine.split('/')[-1], quality=70)
img_io.seek(0)
response = make_response(img_io.getvalue())
img_io.close()
response.headers["Content-Type"] = mine
response.headers["Content-Disposition"] = "attachment; filename={}_label.{}".format(image_name.split('.')[0],
img_type)
return response
return img_io
except Exception as e:
traceback.print_exc()
......
import json
from flask import Blueprint, request, Response
import io
import traceback
import zipfile
from flask import Blueprint, request, Response, make_response, send_file
from dao import Image, Relation
image = Blueprint("image", __name__, url_prefix="/api")
def handle_except(result):
res = {
'code': result.code,
'message': result.message,
'data': result.data
}
return json.dumps(res, ensure_ascii=False)
# 获取图片
@image.route("/image/getImage", methods=["POST"])
def get_image():
......@@ -13,12 +25,7 @@ def get_image():
relation_list = data['relationList']
# relation_list = request.args['relationList']
image = Image.getImage(relation_list)
res = {
'code': image.code,
'message': image.message,
'data': image.data
}
return json.dumps(res, ensure_ascii=False)
return handle_except(image)
# 保存图片标注结果
......@@ -48,12 +55,7 @@ def get_layer():
data = json.loads(request.data)
relation_list = data['relationId']
layer = Image.getLayer(relation_list)
res = {
'code': layer.code,
'message': layer.message,
'data': layer.data
}
return json.dumps(res, ensure_ascii=False)
return handle_except(layer)
# 保存图层标注结果
......@@ -83,49 +85,102 @@ def save_layer():
# 导出原始图片
@image.route("/image/export/original/<relationId>", methods=['GET'])
def export_original_img(relationId):
# 原始图像
original_img = Image.export_original_img(relationId)
if not isinstance(original_img, Response):
res = {
'code': original_img.code,
'message': original_img.message,
'data': original_img.data
}
return json.dumps(res, ensure_ascii=False)
try:
image_name = Image.get_img_name(relationId)
img_type, mine = Image.get_img_type(relationId)
# 原始图像
original_img_bytes = Image.export_original_img_bytes(relationId)
if not isinstance(original_img_bytes, io.BytesIO):
return handle_except(original_img_bytes)
response = make_response(original_img_bytes.getvalue())
original_img_bytes.close()
response.headers["Content-Type"] = mine
response.headers["Content-Disposition"] = "attachment; filename={}".format(image_name)
return response
return original_img
except Exception as e:
traceback.print_exc()
return handle_except(Image.Result(0, repr(e), {}))
# 导出标注图片的 json
@image.route("/image/export/json/<relationId>", methods=['GET'])
def export_json(relationId):
# json
img_json = Image.export_img_json(relationId)
if isinstance(img_json, Image.Result):
res = {
'code': img_json.code,
'message': img_json.message,
'data': img_json.data
}
return json.dumps(res, ensure_ascii=False)
try:
image_name = Image.get_img_name(relationId)
# json
img_json_bytes, _ = Image.export_img_json_bytes(relationId)
if isinstance(img_json_bytes, Image.Result):
return handle_except(img_json_bytes)
response = make_response(img_json_bytes)
response.headers["Content-Disposition"] = "p_w_upload; filename={}.json".format(image_name.split('.')[0])
return response
return img_json
except Exception as e:
traceback.print_exc()
return handle_except(Image.Result(0, repr(e), {}))
# 导出标注后的图片
@image.route("/image/export/label/<relationId>", methods=['GET'])
def export_label(relationId):
# 标注图像
label_img = Image.export_label_img(relationId)
if isinstance(label_img, Image.Result):
res = {
'code': label_img.code,
'message': label_img.message,
'data': label_img.data
}
return json.dumps(res, ensure_ascii=False)
return label_img
try:
# 标注图像
label_img_bytes = Image.export_label_img_bytes(relationId)
image_name = Image.get_img_name(relationId)
img_type, mine = Image.get_img_type(relationId)
if isinstance(label_img_bytes, Image.Result):
return handle_except(label_img_bytes)
response = make_response(label_img_bytes.getvalue())
label_img_bytes.close()
response.headers["Content-Type"] = mine
response.headers["Content-Disposition"] = "attachment; filename={}_label.{}".format(image_name.split('.')[0],
img_type)
return response
except Exception as e:
traceback.print_exc()
return handle_except(Image.Result(0, repr(e), {}))
# 导出压缩文件
@image.route("/image/export/zip/<relationId>", methods=['GET'])
def export_zip(relationId):
try:
image_name = Image.get_img_name(relationId)
img_type = image_name.split('.')[-1].lower()
image_name = image_name.split('.')[0]
# 3 files' Bytes
original_img_bytes = Image.export_original_img_bytes(relationId)
label_img_bytes = Image.export_label_img_bytes(relationId)
_, json_img_bytes = Image.export_img_json_bytes(relationId)
bytes = [original_img_bytes, json_img_bytes, label_img_bytes]
types = [image_name + '.' + img_type, image_name + '.json', image_name + '_label.' + img_type]
# zip file
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
for file_name, data in zip(types, bytes):
zip_file.writestr(file_name, data.getvalue())
data.close()
zip_buffer.seek(0)
return send_file(zip_buffer, attachment_filename=image_name + '.zip', as_attachment=True)
except Exception as e:
traceback.print_exc()
return handle_except(Image.Result(0, repr(e), {}))
# 保存图片标注结果的测试数据
# {
......
......@@ -131,6 +131,14 @@ def get_image_file(imageName):
return jsonify({"code": 0, "errmsg": repr(e)})
# 根据图片名称返回图片所在路径
def get_image_dir(imageName):
file_dir = os.path.join(basedir, UPLOAD_FOLDER, imageName)
if not os.path.exists(file_dir):
return None
return file_dir
# 根据图片名称返回图片的 base64 编码
def get_image_base64(imageName):
try:
......@@ -298,28 +306,29 @@ def downloadZip():
result = mongodbApi.findOne(collectionTest, {"relationId": relationId})
url = result.get('textUrl')
file_dir = os.path.join(basedir, UPLOAD_FOLDER) # 被压缩的文件所在文件夹路径 如 D:\learn\python-project\demo\upload
zip_dir = os.path.join(basedir, ZIP_FOLDER) # 压缩后的文件所在文件夹路径 如 D:\learn\python-project\demo\zip
file_dir = os.path.join(basedir, UPLOAD_FOLDER) # 被压缩的文件所在文件夹路径 如 D:\learn\python-project\demo\upload
zip_dir = os.path.join(basedir, ZIP_FOLDER) # 压缩后的文件所在文件夹路径 如 D:\learn\python-project\demo\zip
portion = os.path.splitext(url) # 获取文件前缀名 如1590310217.txt portion[0]则为1590310217
new_name = portion[0] + '.zip' # 新的文件名字 如1590310217.zip
zipname = os.path.join(zip_dir, new_name) # 压缩的文件夹名字及路径 如 D:\learn\python-project\demo\zip\1590310217.zip (这是我电脑上的路径)
f = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) #创建压缩文件 'w':写模式 ZIP_DEFLATED:设置压缩格式
basename = url #压缩后文件的根目录叫啥
portion = os.path.splitext(url) # 获取文件前缀名 如1590310217.txt portion[0]则为1590310217
new_name = portion[0] + '.zip' # 新的文件名字 如1590310217.zip
zipname = os.path.join(zip_dir,
new_name) # 压缩的文件夹名字及路径 如 D:\learn\python-project\demo\zip\1590310217.zip (这是我电脑上的路径)
f = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) # 创建压缩文件 'w':写模式 ZIP_DEFLATED:设置压缩格式
basename = url # 压缩后文件的根目录叫啥
fpath = os.path.join(file_dir, url) # fpath就是被压缩的文件的路径的集合 file_dir代表被压缩的文件的路径 name是被压缩的文件的名字
arcname = os.path.join(basename, url) # 这个不用管 是为了让压缩后的文件的根目录只有一层 不然会套娃n个文件夹(一层路径一个文件夹)
f.write(fpath, arcname=arcname) #写进去 压缩!
arcname = os.path.join(basename, url) # 这个不用管 是为了让压缩后的文件的根目录只有一层 不然会套娃n个文件夹(一层路径一个文件夹)
f.write(fpath, arcname=arcname) # 写进去 压缩!
json_name = portion[0] + 'result.json' # 新的文件名字 如1590310217result.txt
full_path = os.path.join(file_dir, json_name) # 标注结果文件保存位置 + 标注结果文件名
file = open(full_path, 'w', encoding='utf8') #打开文件
file.write(str(result.get('tokenList'))) #写入标注结果字符串
file.close() #关闭文件
full_path = os.path.join(file_dir, json_name) # 标注结果文件保存位置 + 标注结果文件名
file = open(full_path, 'w', encoding='utf8') # 打开文件
file.write(str(result.get('tokenList'))) # 写入标注结果字符串
file.close() # 关闭文件
fpath = os.path.join(file_dir, json_name) # fpath就是被压缩的文件的路径的集合 file_dir代表被压缩的文件的路径 name是被压缩的文件的名字
arcname = os.path.join(basename, json_name) # 这个不用管 是为了让压缩后的文件的根目录只有一层 不然会套娃n个文件夹(一层路径一个文件夹)
f.write(fpath, arcname=arcname) # 写进去 压缩!
f.close() #关闭
f.close() # 关闭
return send_file(zipname, as_attachment=True, attachment_filename=new_name)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment