Spaces:
Running
Running
import numpy as np | |
from hivision import IDCreator | |
from hivision.error import FaceError, APIError | |
from hivision.utils import add_background, resize_image_to_kb | |
from hivision.creator.layout_calculator import ( | |
generate_layout_photo, | |
generate_layout_image, | |
) | |
from hivision.creator.choose_handler import choose_handler | |
from demo.utils import add_watermark, range_check | |
import gradio as gr | |
import os | |
import time | |
from demo.locals import LOCALES | |
class IDPhotoProcessor: | |
def process( | |
self, | |
input_image, | |
mode_option, | |
size_list_option, | |
color_option, | |
render_option, | |
image_kb_options, | |
custom_color_R, | |
custom_color_G, | |
custom_color_B, | |
custom_size_height, | |
custom_size_width, | |
custom_image_kb, | |
language, | |
matting_model_option, | |
watermark_option, | |
watermark_text, | |
watermark_text_color, | |
watermark_text_size, | |
watermark_text_opacity, | |
watermark_text_angle, | |
watermark_text_space, | |
face_detect_option, | |
head_measure_ratio=0.2, | |
top_distance_max=0.12, | |
top_distance_min=0.10, | |
): | |
top_distance_min = top_distance_max - 0.02 | |
idphoto_json = { | |
"size_mode": mode_option, | |
"color_mode": color_option, | |
"render_mode": render_option, | |
"image_kb_mode": image_kb_options, | |
"custom_image_kb": None, | |
} | |
# 如果尺寸模式选择的是尺寸列表 | |
if idphoto_json["size_mode"] == LOCALES["size_mode"][language]["choices"][0]: | |
idphoto_json["size"] = LOCALES["size_list"][language]["develop"][ | |
size_list_option | |
] | |
# 如果尺寸模式选择的是自定义尺寸 | |
elif idphoto_json["size_mode"] == LOCALES["size_mode"][language]["choices"][2]: | |
id_height = int(custom_size_height) | |
id_width = int(custom_size_width) | |
if ( | |
id_height < id_width | |
or min(id_height, id_width) < 100 | |
or max(id_height, id_width) > 1800 | |
): | |
return [ | |
gr.update(value=None), # img_output_standard | |
gr.update(value=None), # img_output_standard_hd | |
None, # img_output_layout (assuming it should be None or not updated) | |
gr.update( # notification | |
value=LOCALES["size_mode"][language]["custom_size_eror"], | |
visible=True, | |
), | |
None, # file_download (assuming it should be None or not updated) | |
] | |
idphoto_json["size"] = (id_height, id_width) | |
else: | |
idphoto_json["size"] = (None, None) | |
# 如果颜色模式选择的是自定义底色 | |
if idphoto_json["color_mode"] == LOCALES["bg_color"][language]["choices"][-1]: | |
idphoto_json["color_bgr"] = ( | |
range_check(custom_color_R), | |
range_check(custom_color_G), | |
range_check(custom_color_B), | |
) | |
else: | |
hex_color = idphoto_json["color_bgr"] = LOCALES["bg_color"][language][ | |
"develop" | |
][color_option] | |
# 转为 RGB | |
idphoto_json["color_bgr"] = tuple( | |
int(hex_color[i : i + 2], 16) for i in (0, 2, 4) | |
) | |
# 如果输出 KB 大小选择的是自定义 | |
if ( | |
idphoto_json["image_kb_mode"] | |
== LOCALES["image_kb"][language]["choices"][-1] | |
): | |
idphoto_json["custom_image_kb"] = custom_image_kb | |
creator = IDCreator() | |
choose_handler(creator, matting_model_option, face_detect_option) | |
# 是否只换底 | |
change_bg_only = ( | |
idphoto_json["size_mode"] in LOCALES["size_mode"][language]["choices"][1] | |
) | |
try: | |
result = creator( | |
input_image, | |
change_bg_only=change_bg_only, | |
size=idphoto_json["size"], | |
head_measure_ratio=head_measure_ratio, | |
head_top_range=(top_distance_max, top_distance_min), | |
) | |
except FaceError: | |
return [ | |
gr.update(value=None), # img_output_standard | |
gr.update(value=None), # img_output_standard_hd | |
gr.update(visible=False), # img_output_layout | |
gr.update( # notification | |
value=LOCALES["notification"][language]["face_error"], | |
visible=True, | |
), | |
None, # file_download (assuming it should be None or have no update) | |
] | |
except APIError as e: | |
return [ | |
gr.update(value=None), # img_output_standard | |
gr.update(value=None), # img_output_standard_hd | |
gr.update(visible=False), # img_output_layout | |
gr.update( # notification | |
value=LOCALES["notification"][language]["face_error"], | |
visible=True, | |
), | |
None, # file_download (assuming it should be None or have no update) | |
] | |
else: | |
(result_image_standard, result_image_hd, _, _) = result | |
if ( | |
idphoto_json["render_mode"] | |
== LOCALES["render_mode"][language]["choices"][0] | |
): | |
result_image_standard = np.uint8( | |
add_background(result_image_standard, bgr=idphoto_json["color_bgr"]) | |
) | |
result_image_hd = np.uint8( | |
add_background(result_image_hd, bgr=idphoto_json["color_bgr"]) | |
) | |
elif ( | |
idphoto_json["render_mode"] | |
== LOCALES["render_mode"][language]["choices"][1] | |
): | |
result_image_standard = np.uint8( | |
add_background( | |
result_image_standard, | |
bgr=idphoto_json["color_bgr"], | |
mode="updown_gradient", | |
) | |
) | |
result_image_hd = np.uint8( | |
add_background( | |
result_image_hd, | |
bgr=idphoto_json["color_bgr"], | |
mode="updown_gradient", | |
) | |
) | |
else: | |
result_image_standard = np.uint8( | |
add_background( | |
result_image_standard, | |
bgr=idphoto_json["color_bgr"], | |
mode="center_gradient", | |
) | |
) | |
result_image_hd = np.uint8( | |
add_background( | |
result_image_hd, | |
bgr=idphoto_json["color_bgr"], | |
mode="center_gradient", | |
) | |
) | |
# 如果只换底,就不生成排版照 | |
if change_bg_only: | |
result_layout_image = gr.update(visible=False) | |
else: | |
typography_arr, typography_rotate = generate_layout_photo( | |
input_height=idphoto_json["size"][0], | |
input_width=idphoto_json["size"][1], | |
) | |
if ( | |
watermark_option | |
== LOCALES["watermark_switch"][language]["choices"][1] | |
): | |
result_layout_image = gr.update( | |
value=generate_layout_image( | |
add_watermark( | |
image=result_image_standard, | |
text=watermark_text, | |
size=watermark_text_size, | |
opacity=watermark_text_opacity, | |
angle=watermark_text_angle, | |
space=watermark_text_space, | |
color=watermark_text_color, | |
), | |
typography_arr, | |
typography_rotate, | |
height=idphoto_json["size"][0], | |
width=idphoto_json["size"][1], | |
), | |
visible=True, | |
) | |
else: | |
result_layout_image = gr.update( | |
value=generate_layout_image( | |
result_image_standard, | |
typography_arr, | |
typography_rotate, | |
height=idphoto_json["size"][0], | |
width=idphoto_json["size"][1], | |
), | |
visible=True, | |
) | |
# 如果添加水印 | |
if watermark_option == LOCALES["watermark_switch"][language]["choices"][1]: | |
result_image_standard = add_watermark( | |
image=result_image_standard, | |
text=watermark_text, | |
size=watermark_text_size, | |
opacity=watermark_text_opacity, | |
angle=watermark_text_angle, | |
space=watermark_text_space, | |
color=watermark_text_color, | |
) | |
result_image_hd = add_watermark( | |
image=result_image_hd, | |
text=watermark_text, | |
size=watermark_text_size, | |
opacity=watermark_text_opacity, | |
angle=watermark_text_angle, | |
space=watermark_text_space, | |
color=watermark_text_color, | |
) | |
# 如果输出 KB 大小选择的是自定义 | |
if idphoto_json["custom_image_kb"]: | |
print("调整 kb 大小到", idphoto_json["custom_image_kb"], "kb") | |
output_image_path = f"{os.path.join(os.path.dirname(os.path.dirname(__file__)), 'demo/kb_output')}/{int(time.time())}.jpg" | |
resize_image_to_kb( | |
result_image_standard, | |
output_image_path, | |
idphoto_json["custom_image_kb"], | |
) | |
else: | |
output_image_path = None | |
# 返回结果 | |
if output_image_path: | |
return [ | |
result_image_standard, # img_output_standard | |
result_image_hd, # img_output_standard_hd | |
result_layout_image, # img_output_layout | |
gr.update(visible=False), # notification | |
gr.update(visible=True, value=output_image_path), # file_download | |
] | |
else: | |
return [ | |
result_image_standard, # img_output_standard | |
result_image_hd, # img_output_standard_hd | |
result_layout_image, # img_output_layout | |
gr.update(visible=False), # notification | |
gr.update(visible=False), # file_download | |
] | |