mirror of
https://github.com/Zeyi-Lin/HivisionIDPhotos.git
synced 2026-08-28 11:20:47 +08:00
feat: cut layout image (#165)
* style: layout photo -> array * layout photo crop line * v1.2.8
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
|
||||
- 在线体验: [](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link]
|
||||
|
||||
- 2024.09.24: Gradio Demo增加**排版照裁剪线**功能
|
||||
- 2024.09.22: Gradio Demo增加**野兽模式**,可设置内存加载策略 | API接口增加**dpi、face_alignment**参数
|
||||
- 2024.09.18: Gradio Demo增加**分享模版照**功能、增加**美式证件照**背景选项
|
||||
- 2024.09.17: Gradio Demo增加**自定义底色-HEX输入**功能 | **(社区贡献)C++版本** - [HivisionIDPhotos-cpp](https://github.com/zjkhahah/HivisionIDPhotos-cpp) 贡献 by [zjkhahah](https://github.com/zjkhahah)
|
||||
@@ -62,7 +63,6 @@
|
||||
- 2024.09.14: Gradio Demo增加**自定义DPI**功能,增加日语和韩语支持,增加**调整亮度、对比度、锐度**功能
|
||||
- 2024.09.12: Gradio Demo增加**美白**功能 | API接口增加**加水印**、**设置照片KB值大小**、**证件照裁切**
|
||||
- 2024.09.11: Gradio Demo增加**透明图显示与下载**功能
|
||||
- 2024.09.10: 增加新的**人脸检测模型** Retinaface-resnet50,以稍弱于mtcnn的速度换取更高的检测精度,推荐使用
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
+1
-1
@@ -54,6 +54,7 @@ English / [中文](README.md) / [日本語](README_JP.md) / [한국어](README_K
|
||||
|
||||
- Online Experience: [](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link]
|
||||
|
||||
- 2024.09.24: Gradio Demo adds **Layout Photo Crop Line** feature
|
||||
- 2024.09.22: Gradio Demo adds **Beast Mode** and **DPI** parameter
|
||||
- 2024.09.18: Gradio Demo adds **Share Template Photos** feature and **American Style** background option
|
||||
- 2024.09.17: Gradio Demo adds **Custom Background Color-HEX Input** feature | **(Community Contribution) C++ Version** - [HivisionIDPhotos-cpp](https://github.com/zjkhahah/HivisionIDPhotos-cpp) contributed by [zjkhahah](https://github.com/zjkhahah)
|
||||
@@ -61,7 +62,6 @@ English / [中文](README.md) / [日本語](README_JP.md) / [한국어](README_K
|
||||
- 2024.09.14: Gradio Demo adds **Custom DPI** feature, adds Japanese and Korean support, adds **Adjust Brightness, Contrast, Sharpness** feature
|
||||
- 2024.09.12: Gradio Demo adds **Whitening** feature | API interface adds **Watermark**, **Set Photo KB Size**, **ID Photo Cropping**
|
||||
- 2024.09.11: Added **transparent image display and download** feature to Gradio Demo.
|
||||
- 2024.09.10: Added a new **face detection model** Retinaface-resnet50, which offers higher detection accuracy at a slightly slower speed compared to mtcnn. Recommended for use.
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
+1
-1
@@ -51,13 +51,13 @@
|
||||
|
||||
- オンライン体験: [](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link]
|
||||
|
||||
- 2024.09.24: Gradioデモに**排版照裁剪线**機能を追加
|
||||
- 2024.09.22: Gradioデモに**ビーストモード**と**DPI**パラメータを追加
|
||||
- 2024.09.18: Gradioデモに**テンプレート写真の共有**機能を追加、**米国式**背景オプションを追加
|
||||
- 2024.09.17: Gradioデモに**カスタム底色-HEX入力**機能を追加 | **(コミュニティ貢献)C++バージョン** - [HivisionIDPhotos-cpp](https://github.com/zjkhahah/HivisionIDPhotos-cpp) 貢献 by [zjkhahah](https://github.com/zjkhahah)
|
||||
- 2024.09.16: Gradioデモに**顔回転対応**機能を追加、カスタムサイズ入力に**ミリメートル**をサポート
|
||||
- 2024.09.14: Gradioデモに**カスタムDPI**機能を追加、日本語と韓国語を追加,**明るさ、コントラスト、鮮明度の調整**機能を追加
|
||||
- 2024.09.12: Gradioデモに**ホワイトニング**機能を追加 | APIインターフェースに**ウォーターマーク追加**、**写真のKBサイズ設定**、**証明写真のトリミング**を追加
|
||||
- 2024.09.11: Gradioデモに**透過画像表示とダウンロード**機能を追加しました。
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
+1
-1
@@ -51,13 +51,13 @@
|
||||
|
||||
- 온라인 체험: [](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link]
|
||||
|
||||
- 2024.09.24: Gradio Demo에 **排版照裁剪线** 기능 추가
|
||||
- 2024.09.22: Gradio Demo에 **버스트 모드** 및 **DPI** 매개변수 추가
|
||||
- 2024.09.18: Gradio Demo에 **템플릿 사진 공유** 기능 추가, **미국식** 배경 옵션 추가
|
||||
- 2024.09.17: Gradio Demo에 **커스텀 배경색-HEX 입력** 기능 추가 | **(커뮤니티 기여) C++ 버전** - [HivisionIDPhotos-cpp](https://github.com/zjkhahah/HivisionIDPhotos-cpp) 기여 by [zjkhahah](https://github.com/zjkhahah)
|
||||
- 2024.09.16: Gradio Demo에 **얼굴 회전 정렬** 기능 추가, 커스텀 사이즈 입력에 **밀리미터** 단위 추가
|
||||
- 2024.09.14: Gradio Demo에 **커스텀 DPI** 기능 추가, 일본어와 한국어 추가, **밝기, 대비, 선명도 조절** 기능 추가
|
||||
- 2024.09.12: Gradio 데모에 **미백** 기능 추가 | API 인터페이스에 **워터마크 추가**, **사진 KB 크기 설정**, **증명사진 자르기** 추가
|
||||
- 2024.09.11: Gradio Demo에 **투명 이미지 표시 및 다운로드** 기능 추가
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; font-size: 40px;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<img src="https://swanhub.co/git/repo/ZeYiLin%2FHivisionIDPhotos/file/preview?ref=master&path=assets/hivision_logo.png" alt="HivisionIDPhotos" style="width: 65px; height: 65px; margin-right: 10px;" onerror="this.style.display='none';" loading="lazy">
|
||||
<b style="color: #6e9abb;">HivisionIDPhotos</b>
|
||||
<b style="color: #6e9abb;">HivisionIDPhotos</b><span style="font-size: 18px; color: #638fb3; margin-left: 10px;"> v1.2.8</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: center; align-items: center; text-align: center;">
|
||||
<a href="https://github.com/xiaolin199912/HivisionIDPhotos"><img alt="Github" src="https://img.shields.io/static/v1?label=GitHub&message=GitHub&color=black"></a>  
|
||||
|
||||
+9
-9
@@ -667,22 +667,22 @@ LOCALES = {
|
||||
"label": "포화도 강도",
|
||||
},
|
||||
},
|
||||
"face_alignment": {
|
||||
"plugin": {
|
||||
"en": {
|
||||
"label": "Face Alignment",
|
||||
"choices": ["Open"],
|
||||
"label": "🤖Plugin",
|
||||
"choices": ["Face Alignment", "Layout Photo Crop Line"],
|
||||
},
|
||||
"zh": {
|
||||
"label": "人脸旋转对齐",
|
||||
"choices": ["开启"],
|
||||
"label": "🤖插件",
|
||||
"choices": ["人脸旋转对齐", "排版照裁剪线"],
|
||||
},
|
||||
"ja": {
|
||||
"label": "顔の整列",
|
||||
"choices": ["開始"],
|
||||
"label": "🤖プラグイン",
|
||||
"choices": ["顔の整列", "レイアウト写真の切り取り線"],
|
||||
},
|
||||
"ko": {
|
||||
"label": "얼굴 정렬",
|
||||
"choices": ["시작"],
|
||||
"label": "🤖플러그인",
|
||||
"choices": ["얼굴 정렬", "레이아웃 사진 자르기 선"],
|
||||
},
|
||||
},
|
||||
"template_photo": {
|
||||
|
||||
+18
-5
@@ -9,7 +9,7 @@ from hivision.utils import (
|
||||
save_image_dpi_to_bytes,
|
||||
)
|
||||
from hivision.creator.layout_calculator import (
|
||||
generate_layout_photo,
|
||||
generate_layout_array,
|
||||
generate_layout_image,
|
||||
)
|
||||
from hivision.creator.choose_handler import choose_handler
|
||||
@@ -61,16 +61,26 @@ class IDPhotoProcessor:
|
||||
contrast_strength=0,
|
||||
sharpen_strength=0,
|
||||
saturation_strength=0,
|
||||
face_alignment_option=False,
|
||||
):
|
||||
plugin_option=[],
|
||||
):
|
||||
# 初始化参数
|
||||
top_distance_min = top_distance_max - 0.02
|
||||
# 得到render_option在LOCALES["render_mode"][language]["choices"]中的索引
|
||||
render_option_index = LOCALES["render_mode"][language]["choices"].index(
|
||||
render_option
|
||||
)
|
||||
# 读取插件选项
|
||||
if LOCALES["plugin"][language]["choices"][0] in plugin_option:
|
||||
face_alignment_option = True
|
||||
else:
|
||||
face_alignment_option = False
|
||||
if LOCALES["plugin"][language]["choices"][1] in plugin_option:
|
||||
layout_photo_crop_line_option = True
|
||||
else:
|
||||
layout_photo_crop_line_option = False
|
||||
|
||||
idphoto_json = self._initialize_idphoto_json(
|
||||
mode_option, color_option, render_option_index, image_kb_options
|
||||
mode_option, color_option, render_option_index, image_kb_options, layout_photo_crop_line_option
|
||||
)
|
||||
|
||||
# 处理尺寸模式
|
||||
@@ -153,6 +163,7 @@ class IDPhotoProcessor:
|
||||
color_option,
|
||||
render_option,
|
||||
image_kb_options,
|
||||
layout_photo_crop_line_option,
|
||||
):
|
||||
"""初始化idphoto_json字典"""
|
||||
return {
|
||||
@@ -162,6 +173,7 @@ class IDPhotoProcessor:
|
||||
"image_kb_mode": image_kb_options,
|
||||
"custom_image_kb": None,
|
||||
"custom_image_dpi": None,
|
||||
"layout_photo_crop_line_option": layout_photo_crop_line_option,
|
||||
}
|
||||
|
||||
# 处理尺寸模式
|
||||
@@ -435,7 +447,7 @@ class IDPhotoProcessor:
|
||||
if idphoto_json["size_mode"] in LOCALES["size_mode"][language]["choices"][1]:
|
||||
return None, False
|
||||
|
||||
typography_arr, typography_rotate = generate_layout_photo(
|
||||
typography_arr, typography_rotate = generate_layout_array(
|
||||
input_height=idphoto_json["size"][0],
|
||||
input_width=idphoto_json["size"][1],
|
||||
)
|
||||
@@ -446,6 +458,7 @@ class IDPhotoProcessor:
|
||||
typography_rotate,
|
||||
height=idphoto_json["size"][0],
|
||||
width=idphoto_json["size"][1],
|
||||
crop_line=idphoto_json["layout_photo_crop_line_option"],
|
||||
)
|
||||
|
||||
return result_image_layout, True
|
||||
|
||||
+21
-17
@@ -81,12 +81,7 @@ def create_ui(
|
||||
value=LOCALES["size_mode"][DEFAULT_LANG]["choices"][0],
|
||||
min_width=520,
|
||||
)
|
||||
# 人脸对齐
|
||||
face_alignment_options = gr.CheckboxGroup(
|
||||
label=LOCALES["face_alignment"][DEFAULT_LANG]["label"],
|
||||
choices=LOCALES["face_alignment"][DEFAULT_LANG]["choices"],
|
||||
interactive=True,
|
||||
)
|
||||
|
||||
# 尺寸列表
|
||||
with gr.Row(visible=True) as size_list_row:
|
||||
size_list_options = gr.Dropdown(
|
||||
@@ -143,6 +138,14 @@ def create_ui(
|
||||
label=LOCALES["render_mode"][DEFAULT_LANG]["label"],
|
||||
value=LOCALES["render_mode"][DEFAULT_LANG]["choices"][0],
|
||||
)
|
||||
|
||||
with gr.Row():
|
||||
# 插件模式
|
||||
plugin_options = gr.CheckboxGroup(
|
||||
label=LOCALES["plugin"][DEFAULT_LANG]["label"],
|
||||
choices=LOCALES["plugin"][DEFAULT_LANG]["choices"],
|
||||
interactive=True,
|
||||
)
|
||||
|
||||
# TAB2 - 高级参数 ------------------------------------------------
|
||||
with gr.Tab(
|
||||
@@ -525,10 +528,6 @@ def create_ui(
|
||||
saturation_option: gr.update(
|
||||
label=LOCALES["saturation_strength"][language]["label"]
|
||||
),
|
||||
face_alignment_options: gr.update(
|
||||
label=LOCALES["face_alignment"][language]["label"],
|
||||
choices=LOCALES["face_alignment"][language]["choices"],
|
||||
),
|
||||
custom_size_width_px: gr.update(
|
||||
label=LOCALES["custom_size_px"][language]["width"]
|
||||
),
|
||||
@@ -547,6 +546,11 @@ def create_ui(
|
||||
template_image_accordion: gr.update(
|
||||
label=LOCALES["template_photo"][language]["label"]
|
||||
),
|
||||
plugin_options: gr.update(
|
||||
label=LOCALES["plugin"][language]["label"],
|
||||
choices=LOCALES["plugin"][language]["choices"],
|
||||
value=LOCALES["plugin"][language]["choices"][0],
|
||||
),
|
||||
}
|
||||
|
||||
def change_visibility(option, lang, locales_key, custom_component):
|
||||
@@ -571,7 +575,7 @@ def create_ui(
|
||||
custom_size_px: gr.update(visible=False),
|
||||
custom_size_mm: gr.update(visible=True),
|
||||
size_list_row: gr.update(visible=False),
|
||||
face_alignment_options: gr.update(visible=True),
|
||||
plugin_options: gr.update(interactive=True),
|
||||
}
|
||||
# 如果选择自定义尺寸px
|
||||
elif size_option_item == choices[2]:
|
||||
@@ -579,7 +583,7 @@ def create_ui(
|
||||
custom_size_px: gr.update(visible=True),
|
||||
custom_size_mm: gr.update(visible=False),
|
||||
size_list_row: gr.update(visible=False),
|
||||
face_alignment_options: gr.update(visible=True),
|
||||
plugin_options: gr.update(interactive=True),
|
||||
}
|
||||
# 如果选择只换底,则隐藏所有尺寸组件
|
||||
elif size_option_item == choices[1]:
|
||||
@@ -587,7 +591,7 @@ def create_ui(
|
||||
custom_size_px: gr.update(visible=False),
|
||||
custom_size_mm: gr.update(visible=False),
|
||||
size_list_row: gr.update(visible=False),
|
||||
face_alignment_options: gr.update(visible=False),
|
||||
plugin_options: gr.update(interactive=False),
|
||||
}
|
||||
# 如果选择预设尺寸,则隐藏自定义尺寸组件
|
||||
else:
|
||||
@@ -595,7 +599,7 @@ def create_ui(
|
||||
custom_size_px: gr.update(visible=False),
|
||||
custom_size_mm: gr.update(visible=False),
|
||||
size_list_row: gr.update(visible=True),
|
||||
face_alignment_options: gr.update(visible=True),
|
||||
plugin_options: gr.update(interactive=True),
|
||||
}
|
||||
|
||||
def change_image_kb(image_kb_option, lang):
|
||||
@@ -650,7 +654,7 @@ def create_ui(
|
||||
contrast_option,
|
||||
sharpen_option,
|
||||
saturation_option,
|
||||
face_alignment_options,
|
||||
plugin_options,
|
||||
custom_size_width_px,
|
||||
custom_size_height_px,
|
||||
custom_size_width_mm,
|
||||
@@ -669,7 +673,7 @@ def create_ui(
|
||||
custom_size_px,
|
||||
custom_size_mm,
|
||||
size_list_row,
|
||||
face_alignment_options,
|
||||
plugin_options,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -731,7 +735,7 @@ def create_ui(
|
||||
contrast_option,
|
||||
sharpen_option,
|
||||
saturation_option,
|
||||
face_alignment_options,
|
||||
plugin_options,
|
||||
],
|
||||
outputs=[
|
||||
img_output_standard,
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ from fastapi import FastAPI, UploadFile, Form
|
||||
from hivision import IDCreator
|
||||
from hivision.error import FaceError
|
||||
from hivision.creator.layout_calculator import (
|
||||
generate_layout_photo,
|
||||
generate_layout_array,
|
||||
generate_layout_image,
|
||||
)
|
||||
from hivision.creator.choose_handler import choose_handler
|
||||
@@ -173,7 +173,7 @@ async def generate_layout_photos(
|
||||
|
||||
size = (int(height), int(width))
|
||||
|
||||
typography_arr, typography_rotate = generate_layout_photo(
|
||||
typography_arr, typography_rotate = generate_layout_array(
|
||||
input_height=size[0], input_width=size[1]
|
||||
)
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ def judge_layout(
|
||||
return layout_mode, centerBlockWidth_1, centerBlockHeight_1
|
||||
|
||||
|
||||
def generate_layout_photo(input_height, input_width):
|
||||
def generate_layout_array(input_height, input_width):
|
||||
# 1.基础参数表
|
||||
LAYOUT_WIDTH = 1746
|
||||
LAYOUT_HEIGHT = 1180
|
||||
@@ -118,23 +118,63 @@ def generate_layout_photo(input_height, input_width):
|
||||
|
||||
|
||||
def generate_layout_image(
|
||||
input_image, typography_arr, typography_rotate, width=295, height=413
|
||||
input_image, typography_arr, typography_rotate, width=295, height=413, crop_line:bool=False,
|
||||
):
|
||||
# 定义画布的宽度和高度
|
||||
LAYOUT_WIDTH = 1746
|
||||
LAYOUT_HEIGHT = 1180
|
||||
|
||||
# 创建一个白色背景的空白画布
|
||||
white_background = np.zeros([LAYOUT_HEIGHT, LAYOUT_WIDTH, 3], np.uint8)
|
||||
white_background.fill(255)
|
||||
|
||||
# 如果输入图像的高度不等于指定高度,则调整图像大小
|
||||
if input_image.shape[0] != height:
|
||||
input_image = cv2.resize(input_image, (width, height))
|
||||
|
||||
# 如果需要旋转排版,则对图像进行转置和垂直镜像
|
||||
if typography_rotate:
|
||||
input_image = cv2.transpose(input_image)
|
||||
input_image = cv2.flip(input_image, 0) # 0 表示垂直镜像
|
||||
|
||||
# 交换高度和宽度
|
||||
height, width = width, height
|
||||
|
||||
# 将图像按照排版数组中的位置放置到白色背景上
|
||||
for arr in typography_arr:
|
||||
locate_x, locate_y = arr[0], arr[1]
|
||||
white_background[locate_y : locate_y + height, locate_x : locate_x + width] = (
|
||||
input_image
|
||||
)
|
||||
|
||||
if crop_line:
|
||||
# 添加裁剪线
|
||||
line_color = (200, 200, 200) # 浅灰色
|
||||
line_thickness = 1
|
||||
|
||||
# 初始化裁剪线位置列表
|
||||
vertical_lines = []
|
||||
horizontal_lines = []
|
||||
|
||||
# 根据排版数组添加裁剪线
|
||||
for arr in typography_arr:
|
||||
x, y = arr[0], arr[1]
|
||||
if x not in vertical_lines:
|
||||
vertical_lines.append(x)
|
||||
if x + width not in vertical_lines:
|
||||
vertical_lines.append(x + width)
|
||||
if y not in horizontal_lines:
|
||||
horizontal_lines.append(y)
|
||||
if y + height not in horizontal_lines:
|
||||
horizontal_lines.append(y + height)
|
||||
|
||||
# 绘制垂直裁剪线
|
||||
for x in vertical_lines:
|
||||
cv2.line(white_background, (x, 0), (x, LAYOUT_HEIGHT), line_color, line_thickness)
|
||||
|
||||
# 绘制水平裁剪线
|
||||
for y in horizontal_lines:
|
||||
cv2.line(white_background, (0, y), (LAYOUT_WIDTH, y), line_color, line_thickness)
|
||||
|
||||
# 返回排版后的图像
|
||||
return white_background
|
||||
|
||||
@@ -8,7 +8,7 @@ r"""
|
||||
证件照调整
|
||||
"""
|
||||
from .context import Context
|
||||
from .layout_calculator import generate_layout_photo
|
||||
from .layout_calculator import generate_layout_array
|
||||
import hivision.creator.utils as U
|
||||
import numpy as np
|
||||
import math
|
||||
@@ -111,7 +111,7 @@ def adjust_photo(ctx: Context):
|
||||
}
|
||||
|
||||
# Step7. 排版照参数获取
|
||||
typography_arr, typography_rotate = generate_layout_photo(
|
||||
typography_arr, typography_rotate = generate_layout_array(
|
||||
input_height=standard_size[0], input_width=standard_size[1]
|
||||
)
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ from hivision.error import FaceError
|
||||
from hivision.utils import hex_to_rgb, resize_image_to_kb, add_background, save_image_dpi_to_bytes
|
||||
from hivision import IDCreator
|
||||
from hivision.creator.layout_calculator import (
|
||||
generate_layout_photo,
|
||||
generate_layout_array,
|
||||
generate_layout_image,
|
||||
)
|
||||
from hivision.creator.choose_handler import choose_handler
|
||||
@@ -141,7 +141,7 @@ elif args.type == "generate_layout_photos":
|
||||
|
||||
size = (int(args.height), int(args.width))
|
||||
|
||||
typography_arr, typography_rotate = generate_layout_photo(
|
||||
typography_arr, typography_rotate = generate_layout_array(
|
||||
input_height=size[0], input_width=size[1]
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user