diff --git a/demo/assets/american-style.png b/demo/assets/american-style.png new file mode 100644 index 00000000..d6d7057f Binary files /dev/null and b/demo/assets/american-style.png differ diff --git a/demo/locales.py b/demo/locales.py index cbf9355a..61ac1d20 100644 --- a/demo/locales.py +++ b/demo/locales.py @@ -182,22 +182,22 @@ "bg_color": { "en": { "label": "Background color", - "choices": list(color_list_dict_EN.keys()) + ["Custom(RGB)", "Custom(HEX)"], + "choices": list(color_list_dict_EN.keys()) + ["American Style"] + ["Custom(RGB)", "Custom(HEX)"], "develop": color_list_dict_EN, }, "zh": { "label": "背景颜色", - "choices": list(color_list_dict_CN.keys()) + ["自定义(RGB)", "自定义(HEX)"], + "choices": list(color_list_dict_CN.keys()) + ["美式证件照"] + ["自定义(RGB)", "自定义(HEX)"], "develop": color_list_dict_CN, }, "ja": { "label": "背景色", - "choices": list(color_list_dict_EN.keys()) + ["カスタム(RGB)", "カスタム(HEX)"], + "choices": list(color_list_dict_EN.keys()) + ["American Style"] + ["カスタム(RGB)", "カスタム(HEX)"], "develop": color_list_dict_EN, }, "ko": { "label": "배경색", - "choices": list(color_list_dict_EN.keys()) + ["사용자 지정(RGB)", "사용자 지정(HEX)"], + "choices": list(color_list_dict_EN.keys()) + ["American Style"] + ["사용자 지정(RGB)", "사용자 지정(HEX)"], "develop": color_list_dict_EN, }, }, diff --git a/demo/processor.py b/demo/processor.py index 0e3e5204..62663d5e 100644 --- a/demo/processor.py +++ b/demo/processor.py @@ -3,6 +3,7 @@ from hivision.error import FaceError, APIError from hivision.utils import ( add_background, + add_background_with_image, resize_image_to_kb, add_watermark, save_image_dpi_to_bytes, @@ -16,10 +17,13 @@ from demo.utils import range_check import gradio as gr import os +import cv2 import time from demo.locales import LOCALES +base_path = os.path.dirname(os.path.abspath(__file__)) + class IDPhotoProcessor: def process( self, @@ -217,11 +221,12 @@ def _process_color_mode( custom_color_hex_value, ): """处理颜色模式""" - # 如果选择了自定义颜色 + # 如果选择了自定义颜色BGR if idphoto_json["color_mode"] == LOCALES["bg_color"][language]["choices"][-2]: idphoto_json["color_bgr"] = tuple( map(range_check, [custom_color_R, custom_color_G, custom_color_B]) ) + # 如果选择了自定义颜色HEX elif idphoto_json["color_mode"] == LOCALES["bg_color"][language]["choices"][-1]: hex_color = custom_color_hex_value # 将十六进制颜色转换为RGB颜色,如果长度为6,则直接转换,如果长度为7,则去掉#号再转换 @@ -238,6 +243,9 @@ def _process_color_mode( raise ValueError( "Invalid hex color. You can only use 6 or 7 characters. For example: #FFFFFF or FFFFFF" ) + # 如果选择了美式证件照 + elif idphoto_json["color_mode"] == LOCALES["bg_color"][language]["choices"][-3]: + idphoto_json["color_bgr"] = (255, 255, 255) else: hex_color = LOCALES["bg_color"][language]["develop"][color_option] idphoto_json["color_bgr"] = tuple( @@ -311,7 +319,7 @@ def _process_generated_photo( # 渲染背景 result_image_standard, result_image_hd = self._render_background( - result_image_standard, result_image_hd, idphoto_json + result_image_standard, result_image_hd, idphoto_json, language ) # 添加水印 @@ -383,22 +391,36 @@ def _process_generated_photo( ) # 渲染背景 - def _render_background(self, result_image_standard, result_image_hd, idphoto_json): + def _render_background(self, result_image_standard, result_image_hd, idphoto_json, language): """渲染背景""" render_modes = {0: "pure_color", 1: "updown_gradient", 2: "center_gradient"} render_mode = render_modes[idphoto_json["render_mode"]] - result_image_standard = np.uint8( - add_background( - result_image_standard, bgr=idphoto_json["color_bgr"], mode=render_mode + if idphoto_json["color_mode"] != LOCALES["bg_color"][language]["choices"][-3]: + result_image_standard = np.uint8( + add_background( + result_image_standard, bgr=idphoto_json["color_bgr"], mode=render_mode + ) ) - ) - result_image_hd = np.uint8( - add_background( - result_image_hd, bgr=idphoto_json["color_bgr"], mode=render_mode + result_image_hd = np.uint8( + add_background( + result_image_hd, bgr=idphoto_json["color_bgr"], mode=render_mode + ) + ) + # 如果选择了美式证件照 + else: + result_image_standard = np.uint8( + add_background_with_image( + result_image_standard, + background_image=cv2.imread(os.path.join(base_path, "assets", "american-style.png")) + ) + ) + result_image_hd = np.uint8( + add_background_with_image( + result_image_hd, + background_image=cv2.imread(os.path.join(base_path, "assets", "american-style.png")) + ) ) - ) - return result_image_standard, result_image_hd # 生成排版照片 @@ -427,7 +449,8 @@ def _generate_image_layout( ) return result_image_layout, True - + + # 生成模板照片 def _generate_image_template( self, idphoto_json, diff --git a/hivision/utils.py b/hivision/utils.py index c087b388..0a862186 100644 --- a/hivision/utils.py +++ b/hivision/utils.py @@ -298,6 +298,36 @@ def add_background(input_image, bgr=(0, 0, 0), mode="pure_color"): return output +def add_background_with_image(input_image: np.ndarray, background_image: np.ndarray) -> np.ndarray: + """ + 本函数的功能为为透明图像加上背景。 + :param input_image: numpy.array(4 channels), 透明图像 + :param background_image: numpy.array(3 channels), 背景图像 + :return: output: 合成好的输出图像 + """ + height, width = input_image.shape[:2] + try: + b, g, r, a = cv2.split(input_image) + except ValueError: + raise ValueError( + "The input image must have 4 channels. 输入图像必须有4个通道,即透明图像。" + ) + + # 确保背景图像与输入图像大小一致 + background_image = cv2.resize(background_image, (width, height), cv2.INTER_AREA) + background_image = cv2.cvtColor(background_image, cv2.COLOR_BGR2RGB) + b2, g2, r2 = cv2.split(background_image) + + a_cal = a / 255.0 + + # 修正混合公式 + output = cv2.merge( + (b * a_cal + b2 * (1 - a_cal), + g * a_cal + g2 * (1 - a_cal), + r * a_cal + r2 * (1 - a_cal)) + ) + + return output.astype(np.uint8) def add_watermark( image, text, size=50, opacity=0.5, angle=45, color="#8B8B1B", space=75