TheEeeeLin commited on
Commit
ec5a4d3
·
1 Parent(s): ff0f164
demo/assets/title.md CHANGED
@@ -4,10 +4,10 @@
4
  <b style="color: #6e9abb;">HivisionIDPhotos</b><span style="font-size: 18px; color: #638fb3; margin-left: 10px;"> v1.2.8</span>
5
  </div>
6
  <div style="display: flex; justify-content: center; align-items: center; text-align: center;">
7
- <a href="https://github.com/xiaolin199912/HivisionIDPhotos"><img alt="Github" src="https://img.shields.io/static/v1?label=GitHub&message=GitHub&color=black"></a> &ensp;
8
- <a href="https://docs.qq.com/doc/DUkpBdk90eWZFS2JW" target="_blank"><img alt="Static Badge" src="https://img.shields.io/badge/WeChat-微信-4cb55e"></a> &ensp;
9
- <a href="https://github.com/xiaolin199912/HivisionIDPhotos/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/zeyi-lin/hivisionidphotos?color=ffcb47&labelColor=black&style=flat-square"></a> &ensp;
10
- <a href="https://swanlab.cn?utm_source=hivision_demo"><img alt="SwanLab" src="https://img.shields.io/badge/Training%20by-SwanLab-4cb55e"></a> &ensp;
11
- <a href="https://github.com/Zeyi-Lin/HivisionIDPhotos/blob/master/docs/api_CN.md" target="_blank"><img alt="Static Badge" src="https://img.shields.io/badge/API_Docs-API文档-315bce"></a>
12
  </div>
13
  </div>
 
4
  <b style="color: #6e9abb;">HivisionIDPhotos</b><span style="font-size: 18px; color: #638fb3; margin-left: 10px;"> v1.2.8</span>
5
  </div>
6
  <div style="display: flex; justify-content: center; align-items: center; text-align: center;">
7
+ <a href="https://github.com/xiaolin199912/HivisionIDPhotos"><img alt="Github" src="https://img.shields.io/static/v1?label=GitHub&message=GitHub&color=black" onerror="this.style.display='none';"></a> &ensp;
8
+ <a href="https://docs.qq.com/doc/DUkpBdk90eWZFS2JW" target="_blank"><img alt="Static Badge" src="https://img.shields.io/badge/WeChat-微信-4cb55e" onerror="this.style.display='none';"></a> &ensp;
9
+ <a href="https://github.com/xiaolin199912/HivisionIDPhotos/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/zeyi-lin/hivisionidphotos?color=ffcb47&labelColor=black&style=flat-square" onerror="this.style.display='none';"></a> &ensp;
10
+ <a href="https://swanlab.cn?utm_source=hivision_demo"><img alt="SwanLab" src="https://img.shields.io/badge/Training%20by-SwanLab-4cb55e" onerror="this.style.display='none';"></a> &ensp;
11
+ <a href="https://github.com/Zeyi-Lin/HivisionIDPhotos/blob/master/docs/api_CN.md" target="_blank"><img alt="Static Badge" src="https://img.shields.io/badge/API_Docs-API文档-315bce" onerror="this.style.display='none';"></a>
12
  </div>
13
  </div>
demo/kb_output/.gitkeep DELETED
File without changes
demo/locales.py CHANGED
@@ -546,7 +546,7 @@ LOCALES = {
546
  "label": "Layout photo",
547
  },
548
  "zh": {
549
- "label": "六寸排版照",
550
  },
551
  "ja": {
552
  "label": "レイアウト写真",
@@ -670,19 +670,23 @@ LOCALES = {
670
  "plugin": {
671
  "en": {
672
  "label": "🤖Plugin",
673
- "choices": ["Face Alignment", "Layout Photo Crop Line"],
 
674
  },
675
  "zh": {
676
  "label": "🤖插件",
677
- "choices": ["人脸旋转对齐", "排版照裁剪线"],
 
678
  },
679
  "ja": {
680
  "label": "🤖プラグイン",
681
- "choices": ["顔の整列", "レイアウト写真の切り取り線"],
 
682
  },
683
  "ko": {
684
  "label": "🤖플러그인",
685
- "choices": ["얼굴 정렬", "레이아웃 사진 자르기 선"],
 
686
  },
687
  },
688
  "template_photo": {
 
546
  "label": "Layout photo",
547
  },
548
  "zh": {
549
+ "label": "排版照",
550
  },
551
  "ja": {
552
  "label": "レイアウト写真",
 
670
  "plugin": {
671
  "en": {
672
  "label": "🤖Plugin",
673
+ "choices": ["Face Alignment", "Layout Photo Crop Line", "JPEG Format", "Five Inch Paper"],
674
+ "value": ["Layout Photo Crop Line"]
675
  },
676
  "zh": {
677
  "label": "🤖插件",
678
+ "choices": ["人脸旋转对齐", "排版照裁剪线", "JPEG格式", "五寸相纸"],
679
+ "value": ["排版照裁剪线"]
680
  },
681
  "ja": {
682
  "label": "🤖プラグイン",
683
+ "choices": ["顔の整列", "レイアウト写真の切り取り線", "JPEGフォーマット", "五寸相紙"],
684
+ "value": ["レイアウト写真の切り取り線"]
685
  },
686
  "ko": {
687
  "label": "🤖플러그인",
688
+ "choices": ["얼굴 정렬", "레이아웃 사진 자르기 선", "JPEG 포맷", "오렌지 사진"],
689
+ "value": ["레이아웃 사진 자르기 선"]
690
  },
691
  },
692
  "template_photo": {
demo/processor.py CHANGED
@@ -70,17 +70,29 @@ class IDPhotoProcessor:
70
  render_option
71
  )
72
  # 读取插件选项
 
73
  if LOCALES["plugin"][language]["choices"][0] in plugin_option:
74
  face_alignment_option = True
75
  else:
76
  face_alignment_option = False
 
77
  if LOCALES["plugin"][language]["choices"][1] in plugin_option:
78
  layout_photo_crop_line_option = True
79
  else:
80
  layout_photo_crop_line_option = False
 
 
 
 
 
 
 
 
 
 
81
 
82
  idphoto_json = self._initialize_idphoto_json(
83
- mode_option, color_option, render_option_index, image_kb_options, layout_photo_crop_line_option
84
  )
85
 
86
  # 处理尺寸模式
@@ -164,6 +176,8 @@ class IDPhotoProcessor:
164
  render_option,
165
  image_kb_options,
166
  layout_photo_crop_line_option,
 
 
167
  ):
168
  """初始化idphoto_json字典"""
169
  return {
@@ -174,6 +188,8 @@ class IDPhotoProcessor:
174
  "custom_image_kb": None,
175
  "custom_image_dpi": None,
176
  "layout_photo_crop_line_option": layout_photo_crop_line_option,
 
 
177
  }
178
 
179
  # 处理尺寸模式
@@ -362,45 +378,27 @@ class IDPhotoProcessor:
362
  )
363
 
364
  # 调整图片大小
365
- output_image_path_dict = self._resize_image_if_needed(
366
  result_image_standard,
367
  result_image_hd,
368
  result_image_layout,
369
  idphoto_json,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  )
371
-
372
- # 如果output_image_path_dict为None,即没有设置KB和DPI
373
- if output_image_path_dict is None:
374
- return self._create_response(
375
- result_image_standard,
376
- result_image_hd,
377
- result_image_standard_png,
378
- result_image_hd_png,
379
- gr.update(value=result_image_layout, visible=result_image_layout_visible),
380
- gr.update(value=result_image_template, visible=result_image_template_visible),
381
- gr.update(visible = result_image_template_visible),
382
- )
383
- # 如果output_image_path_dict不为None,即设置了KB和DPI
384
- else:
385
- if output_image_path_dict["layout"]["processed"]:
386
- result_image_layout = output_image_path_dict["layout"]["path"]
387
- return self._create_response(
388
- (
389
- output_image_path_dict["standard"]["path"]
390
- if output_image_path_dict["standard"]["processed"]
391
- else result_image_standard
392
- ),
393
- (
394
- output_image_path_dict["hd"]["path"]
395
- if output_image_path_dict["hd"]["processed"]
396
- else result_image_hd
397
- ),
398
- result_image_standard_png,
399
- result_image_hd_png,
400
- gr.update(value=result_image_layout, visible=result_image_layout_visible),
401
- gr.update(value=result_image_template, visible=result_image_template_visible),
402
- gr.update(visible = result_image_template_visible),
403
- )
404
 
405
  # 渲染背景
406
  def _render_background(self, result_image_standard, result_image_hd, idphoto_json, language):
@@ -450,6 +448,8 @@ class IDPhotoProcessor:
450
  typography_arr, typography_rotate = generate_layout_array(
451
  input_height=idphoto_json["size"][0],
452
  input_width=idphoto_json["size"][1],
 
 
453
  )
454
 
455
  result_image_layout = generate_layout_image(
@@ -459,6 +459,8 @@ class IDPhotoProcessor:
459
  height=idphoto_json["size"][0],
460
  width=idphoto_json["size"][1],
461
  crop_line=idphoto_json["layout_photo_crop_line_option"],
 
 
462
  )
463
 
464
  return result_image_layout, True
@@ -512,7 +514,7 @@ class IDPhotoProcessor:
512
  result_image_hd = add_watermark(image=result_image_hd, **watermark_params)
513
  return result_image_standard, result_image_hd
514
 
515
- def _resize_image_if_needed(
516
  self,
517
  result_image_standard,
518
  result_image_hd,
@@ -520,11 +522,9 @@ class IDPhotoProcessor:
520
  idphoto_json,
521
  format="png",
522
  ):
523
- """如果需要,调整图片大小"""
524
- # 设置输出路径
525
- base_path = os.path.join(
526
- os.path.dirname(os.path.dirname(__file__)), "demo/kb_output"
527
- )
528
  timestamp = int(time.time())
529
  output_paths = {
530
  "standard": {
@@ -556,53 +556,78 @@ class IDPhotoProcessor:
556
  custom_kb,
557
  dpi=custom_dpi,
558
  )
559
- output_paths["standard"]["processed"] = True
560
  # 保存高清图像和排版图像
561
  save_image_dpi_to_bytes(
562
  result_image_hd, output_paths["hd"]["path"], dpi=custom_dpi
563
  )
564
- output_paths["hd"]["processed"] = True
565
  if result_image_layout is not None:
566
  save_image_dpi_to_bytes(
567
  result_image_layout, output_paths["layout"]["path"], dpi=custom_dpi
568
  )
569
- output_paths["layout"]["processed"] = True
570
 
571
  return output_paths
572
 
573
  # 只有自定义DPI的情况
574
  elif custom_dpi:
575
  for key in output_paths:
576
- output_paths[key]["path"] += f"_{custom_dpi}dpi.{format}"
577
  # 保存所有图像,使用自定义DPI
 
578
  if key == "layout" and result_image_layout is None:
579
- pass
580
- else:
581
- save_image_dpi_to_bytes(
582
- locals()[f"result_image_{key}"],
583
- output_paths[key]["path"],
584
- dpi=custom_dpi,
585
- )
586
- output_paths[key]["processed"] = True
587
 
588
  return output_paths
589
 
590
  # 只有自定义KB的情况
591
  elif custom_kb:
592
  output_paths["standard"]["path"] += f"_{custom_kb}kb.{format}"
593
- # 只调整标准图像大小并保存
 
 
 
 
594
  resize_image_to_kb(
595
  result_image_standard,
596
  output_paths["standard"]["path"],
597
  custom_kb,
598
  dpi=300,
599
  )
600
- output_paths["standard"]["processed"] = True
 
 
 
 
 
 
 
 
601
 
602
  return output_paths
603
-
604
- # 如果没有自定义设置,返回None
605
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
606
 
607
  def _create_response(
608
  self,
@@ -613,7 +638,7 @@ class IDPhotoProcessor:
613
  result_layout_image_gr,
614
  result_image_template_gr,
615
  result_image_template_accordion_gr,
616
- ):
617
  """创建响应"""
618
  response = [
619
  result_image_standard,
 
70
  render_option
71
  )
72
  # 读取插件选项
73
+ # 人脸对齐选项
74
  if LOCALES["plugin"][language]["choices"][0] in plugin_option:
75
  face_alignment_option = True
76
  else:
77
  face_alignment_option = False
78
+ # 排版裁剪线选项
79
  if LOCALES["plugin"][language]["choices"][1] in plugin_option:
80
  layout_photo_crop_line_option = True
81
  else:
82
  layout_photo_crop_line_option = False
83
+ # JPEG格式选项
84
+ if LOCALES["plugin"][language]["choices"][2] in plugin_option:
85
+ jpeg_format_option = True
86
+ else:
87
+ jpeg_format_option = False
88
+ # 五寸相纸选项
89
+ if LOCALES["plugin"][language]["choices"][3] in plugin_option:
90
+ five_inch_option = True
91
+ else:
92
+ five_inch_option = False
93
 
94
  idphoto_json = self._initialize_idphoto_json(
95
+ mode_option, color_option, render_option_index, image_kb_options, layout_photo_crop_line_option, jpeg_format_option, five_inch_option
96
  )
97
 
98
  # 处理尺寸模式
 
176
  render_option,
177
  image_kb_options,
178
  layout_photo_crop_line_option,
179
+ jpeg_format_option,
180
+ five_inch_option,
181
  ):
182
  """初始化idphoto_json字典"""
183
  return {
 
188
  "custom_image_kb": None,
189
  "custom_image_dpi": None,
190
  "layout_photo_crop_line_option": layout_photo_crop_line_option,
191
+ "jpeg_format_option": jpeg_format_option,
192
+ "five_inch_option": five_inch_option,
193
  }
194
 
195
  # 处理尺寸模式
 
378
  )
379
 
380
  # 调整图片大小
381
+ output_image_path_dict = self._save_image(
382
  result_image_standard,
383
  result_image_hd,
384
  result_image_layout,
385
  idphoto_json,
386
+ format="jpeg" if idphoto_json["jpeg_format_option"] else "png",
387
+ )
388
+
389
+ # 返回
390
+ if result_image_layout is not None:
391
+ result_image_layout = output_image_path_dict["layout"]["path"]
392
+
393
+ return self._create_response(
394
+ output_image_path_dict["standard"]["path"],
395
+ output_image_path_dict["hd"]["path"],
396
+ result_image_standard_png,
397
+ result_image_hd_png,
398
+ gr.update(value=result_image_layout, visible=result_image_layout_visible),
399
+ gr.update(value=result_image_template, visible=result_image_template_visible),
400
+ gr.update(visible = result_image_template_visible),
401
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
 
403
  # 渲染背景
404
  def _render_background(self, result_image_standard, result_image_hd, idphoto_json, language):
 
448
  typography_arr, typography_rotate = generate_layout_array(
449
  input_height=idphoto_json["size"][0],
450
  input_width=idphoto_json["size"][1],
451
+ LAYOUT_HEIGHT= 1205 if not idphoto_json["five_inch_option"] else 1051,
452
+ LAYOUT_WIDTH= 1795 if not idphoto_json["five_inch_option"] else 1500,
453
  )
454
 
455
  result_image_layout = generate_layout_image(
 
459
  height=idphoto_json["size"][0],
460
  width=idphoto_json["size"][1],
461
  crop_line=idphoto_json["layout_photo_crop_line_option"],
462
+ LAYOUT_HEIGHT=1205 if not idphoto_json["five_inch_option"] else 1051,
463
+ LAYOUT_WIDTH=1795 if not idphoto_json["five_inch_option"] else 1500,
464
  )
465
 
466
  return result_image_layout, True
 
514
  result_image_hd = add_watermark(image=result_image_hd, **watermark_params)
515
  return result_image_standard, result_image_hd
516
 
517
+ def _save_image(
518
  self,
519
  result_image_standard,
520
  result_image_hd,
 
522
  idphoto_json,
523
  format="png",
524
  ):
525
+ # 设置输出路径(临时目录)
526
+ import tempfile
527
+ base_path = tempfile.mkdtemp()
 
 
528
  timestamp = int(time.time())
529
  output_paths = {
530
  "standard": {
 
556
  custom_kb,
557
  dpi=custom_dpi,
558
  )
 
559
  # 保存高清图像和排版图像
560
  save_image_dpi_to_bytes(
561
  result_image_hd, output_paths["hd"]["path"], dpi=custom_dpi
562
  )
 
563
  if result_image_layout is not None:
564
  save_image_dpi_to_bytes(
565
  result_image_layout, output_paths["layout"]["path"], dpi=custom_dpi
566
  )
 
567
 
568
  return output_paths
569
 
570
  # 只有自定义DPI的情况
571
  elif custom_dpi:
572
  for key in output_paths:
 
573
  # 保存所有图像,使用自定义DPI
574
+ # 如果只换底,则不保存排版图像
575
  if key == "layout" and result_image_layout is None:
576
+ continue
577
+ output_paths[key]["path"] += f"_{custom_dpi}dpi.{format}"
578
+ save_image_dpi_to_bytes(
579
+ locals()[f"result_image_{key}"],
580
+ output_paths[key]["path"],
581
+ dpi=custom_dpi,
582
+ )
 
583
 
584
  return output_paths
585
 
586
  # 只有自定义KB的情况
587
  elif custom_kb:
588
  output_paths["standard"]["path"] += f"_{custom_kb}kb.{format}"
589
+ output_paths["hd"]["path"] += f".{format}"
590
+ if not (key == "layout" and result_image_layout is None):
591
+ output_paths[key]["path"] += f".{format}"
592
+
593
+ # 只调整标准图像大小
594
  resize_image_to_kb(
595
  result_image_standard,
596
  output_paths["standard"]["path"],
597
  custom_kb,
598
  dpi=300,
599
  )
600
+
601
+ # 保存高清图像和排版图像
602
+ save_image_dpi_to_bytes(
603
+ result_image_hd, output_paths["hd"]["path"], dpi=300
604
+ )
605
+ if result_image_layout is not None:
606
+ save_image_dpi_to_bytes(
607
+ result_image_layout, output_paths["layout"]["path"], dpi=300
608
+ )
609
 
610
  return output_paths
611
+ # 没有自定义设置
612
+ else:
613
+ output_paths["standard"]["path"] += f".{format}"
614
+ output_paths["hd"]["path"] += f".{format}"
615
+ output_paths["layout"]["path"] += f".{format}"
616
+
617
+ # 保存所有图像
618
+ save_image_dpi_to_bytes(
619
+ result_image_standard, output_paths["standard"]["path"], dpi=300
620
+ )
621
+ save_image_dpi_to_bytes(
622
+ result_image_hd, output_paths["hd"]["path"], dpi=300
623
+ )
624
+ if result_image_layout is not None:
625
+ save_image_dpi_to_bytes(
626
+ result_image_layout, output_paths["layout"]["path"], dpi=300
627
+ )
628
+
629
+ return output_paths
630
+
631
 
632
  def _create_response(
633
  self,
 
638
  result_layout_image_gr,
639
  result_image_template_gr,
640
  result_image_template_accordion_gr,
641
+ ):
642
  """创建响应"""
643
  response = [
644
  result_image_standard,
demo/ui.py CHANGED
@@ -148,6 +148,7 @@ def create_ui(
148
  label=LOCALES["plugin"][DEFAULT_LANG]["label"],
149
  choices=LOCALES["plugin"][DEFAULT_LANG]["choices"],
150
  interactive=True,
 
151
  )
152
 
153
  # TAB2 - 高级参数 ------------------------------------------------
 
148
  label=LOCALES["plugin"][DEFAULT_LANG]["label"],
149
  choices=LOCALES["plugin"][DEFAULT_LANG]["choices"],
150
  interactive=True,
151
+ value=LOCALES["plugin"][DEFAULT_LANG]["value"]
152
  )
153
 
154
  # TAB2 - 高级参数 ------------------------------------------------
hivision/creator/layout_calculator.py CHANGED
@@ -75,10 +75,8 @@ def judge_layout(
75
  return layout_mode, centerBlockWidth_1, centerBlockHeight_1
76
 
77
 
78
- def generate_layout_array(input_height, input_width):
79
  # 1.基础参数表
80
- LAYOUT_WIDTH = 1746
81
- LAYOUT_HEIGHT = 1180
82
  PHOTO_INTERVAL_H = 30 # 证件照与证件照之间的垂直距离
83
  PHOTO_INTERVAL_W = 30 # 证件照与证件照之间的水平距离
84
  SIDES_INTERVAL_H = 50 # 证件照与画布边缘的垂直距离
@@ -118,12 +116,12 @@ def generate_layout_array(input_height, input_width):
118
 
119
 
120
  def generate_layout_image(
121
- input_image, typography_arr, typography_rotate, width=295, height=413, crop_line:bool=False,
 
 
 
122
  ):
123
- # 定义画布的宽度和高度
124
- LAYOUT_WIDTH = 1746
125
- LAYOUT_HEIGHT = 1180
126
-
127
  # 创建一个白色背景的空白画布
128
  white_background = np.zeros([LAYOUT_HEIGHT, LAYOUT_WIDTH, 3], np.uint8)
129
  white_background.fill(255)
 
75
  return layout_mode, centerBlockWidth_1, centerBlockHeight_1
76
 
77
 
78
+ def generate_layout_array(input_height, input_width, LAYOUT_WIDTH=1795, LAYOUT_HEIGHT=1205):
79
  # 1.基础参数表
 
 
80
  PHOTO_INTERVAL_H = 30 # 证件照与证件照之间的垂直距离
81
  PHOTO_INTERVAL_W = 30 # 证件照与证件照之间的水平距离
82
  SIDES_INTERVAL_H = 50 # 证件照与画布边缘的垂直距离
 
116
 
117
 
118
  def generate_layout_image(
119
+ input_image, typography_arr, typography_rotate, width=295, height=413,
120
+ crop_line:bool=False,
121
+ LAYOUT_WIDTH=1795,
122
+ LAYOUT_HEIGHT=1205,
123
  ):
124
+
 
 
 
125
  # 创建一个白色背景的空白画布
126
  white_background = np.zeros([LAYOUT_HEIGHT, LAYOUT_WIDTH, 3], np.uint8)
127
  white_background.fill(255)