From fe8886f46697b062e0d0e9c0d78287d75fa6f84f Mon Sep 17 00:00:00 2001 From: Ze-Yi LIN <58305964+Zeyi-Lin@users.noreply.github.com> Date: Mon, 23 Sep 2024 08:47:12 +0800 Subject: [PATCH] feat: sync api (#161) * align + hd + dpi * sync inference * sync api * docs * Update README.md * refactor api_CN * docs update --- .gitignore | 3 + README.md | 4 +- README_EN.md | 4 +- README_JP.md | 4 +- README_KO.md | 2 +- deploy_api.py | 84 ++++---- docs/api_CN.md | 371 ++++++--------------------------- docs/api_EN.md | 463 ++++++++++++++--------------------------- docs/api_JP.md | 513 --------------------------------------------- docs/api_KO.md | 515 ---------------------------------------------- hivision/utils.py | 22 +- inference.py | 52 +++-- 12 files changed, 317 insertions(+), 1720 deletions(-) delete mode 100644 docs/api_JP.md delete mode 100644 docs/api_KO.md diff --git a/.gitignore b/.gitignore index a73d9102..bc5beba6 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ test/temp/* .python-version +# Ignore .png and .jpg files in the root directory +/*.png +/*.jpg diff --git a/README.md b/README.md index 0b519d4d..a9ca6ec7 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ - 在线体验: [![SwanHub Demo](https://img.shields.io/static/v1?label=Demo&message=SwanHub%20Demo&color=blue)](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[![Spaces](https://img.shields.io/badge/🤗-Open%20in%20Spaces-blue)](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link] -- 2024.09.22: 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) - 2024.09.16: Gradio Demo增加**人脸旋转对齐**功能,自定义尺寸输入支持**毫米**单位 @@ -256,8 +256,6 @@ python deploy_api.py 详细请求方式请参考 [API 文档](docs/api_CN.md),包含以下请求示例: - [cURL](docs/api_CN.md#curl-请求示例) - [Python](docs/api_CN.md#python-请求示例) -- [Java](docs/api_CN.md#java-请求示例) -- [Javascript](docs/api_CN.md#javascript-请求示例)
diff --git a/README_EN.md b/README_EN.md index 5293ed05..01311a0e 100644 --- a/README_EN.md +++ b/README_EN.md @@ -54,6 +54,7 @@ English / [中文](README.md) / [日本語](README_JP.md) / [한국어](README_K - Online Experience: [![SwanHub Demo](https://img.shields.io/static/v1?label=Demo&message=SwanHub%20Demo&color=blue)](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[![Spaces](https://img.shields.io/badge/🤗-Open%20in%20Spaces-blue)](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link] +- 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) - 2024.09.16: Gradio Demo adds **Face Rotation Alignment** feature, custom size input supports **millimeters** @@ -61,7 +62,6 @@ English / [中文](README.md) / [日本語](README_JP.md) / [한국어](README_K - 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. -- 2024.09.09: Added a new **Background Removal Model** [BiRefNet-v1-lite](https://github.com/ZhengPeng7/BiRefNet) | Gradio added **Advanced Parameter Settings** and **Watermark** tabs
@@ -252,8 +252,6 @@ python deploy_api.py For detailed request methods, please refer to the [API Documentation](docs/api_EN.md), which includes the following request examples: - [cURL](docs/api_EN.md#curl-request-examples) - [Python](docs/api_EN.md#python-request-example) -- [Java](docs/api_EN.md#java-request-example) -- [Javascript](docs/api_EN.md#javascript-request-examples)
diff --git a/README_JP.md b/README_JP.md index e254d9d3..ee05f150 100644 --- a/README_JP.md +++ b/README_JP.md @@ -51,13 +51,13 @@ - オンライン体験: [![SwanHub Demo](https://img.shields.io/static/v1?label=Demo&message=SwanHub%20Demo&color=blue)](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[![Spaces](https://img.shields.io/badge/🤗-Open%20in%20Spaces-blue)](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link] +- 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デモに**透過画像表示とダウンロード**機能を追加しました。 -- 2024.09.09: 新しい**背景除去モデル** [BiRefNet-v1-lite](https://github.com/ZhengPeng7/BiRefNet) を追加 | Gradioに**高度なパラメータ設定**および**ウォーターマーク**タブを追加
@@ -248,8 +248,6 @@ python deploy_api.py 詳細なリクエスト方法は[APIドキュメント](docs/api_EN.md)を参照してください。以下のリクエスト例が含まれます: - [cURL](docs/api_EN.md#curl-request-examples) - [Python](docs/api_EN.md#python-request-example) -- [Java](docs/api_EN.md#java-request-example) -- [Javascript](docs/api_EN.md#javascript-request-examples)
diff --git a/README_KO.md b/README_KO.md index 57b39926..731aa5ab 100644 --- a/README_KO.md +++ b/README_KO.md @@ -51,13 +51,13 @@ - 온라인 체험: [![SwanHub Demo](https://img.shields.io/static/v1?label=Demo&message=SwanHub%20Demo&color=blue)](https://swanhub.co/ZeYiLin/HivisionIDPhotos/demo)、[![Spaces](https://img.shields.io/badge/🤗-Open%20in%20Spaces-blue)](https://huggingface.co/spaces/TheEeeeLin/HivisionIDPhotos)、[![][modelscope-shield]][modelscope-link] +- 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에 **투명 이미지 표시 및 다운로드** 기능 추가 -- 2024.09.09: 새로운 **배경 제거 모델** [BiRefNet-v1-lite](https://github.com/ZhengPeng7/BiRefNet) 추가 | Gradio에 **고급 매개변수 설정** 및 **워터마크** 탭 추가
diff --git a/deploy_api.py b/deploy_api.py index 2e7af0c6..8eab422a 100644 --- a/deploy_api.py +++ b/deploy_api.py @@ -8,9 +8,12 @@ from hivision.creator.choose_handler import choose_handler from hivision.utils import ( add_background, - resize_image_to_kb_base64, + resize_image_to_kb, + bytes_2_base64, + numpy_2_base64, hex_to_rgb, add_watermark, + save_image_dpi_to_bytes, ) import base64 import numpy as np @@ -32,23 +35,17 @@ ) -# 将图像转换为Base64编码 -def numpy_2_base64(img: np.ndarray): - retval, buffer = cv2.imencode(".png", img) - base64_image = base64.b64encode(buffer).decode("utf-8") - - return "data:image/png;base64," + base64_image - - # 证件照智能制作接口 @app.post("/idphoto") async def idphoto_inference( input_image: UploadFile, height: int = Form(413), width: int = Form(295), - human_matting_model: str = Form("hivision_modnet"), + human_matting_model: str = Form("modnet_photographic_portrait_matting"), face_detect_model: str = Form("mtcnn"), hd: bool = Form(True), + dpi: int = Form(300), + face_align: bool = Form(False), head_measure_ratio: float = 0.2, head_height_ratio: float = 0.45, top_distance_max: float = 0.12, @@ -70,19 +67,23 @@ async def idphoto_inference( head_measure_ratio=head_measure_ratio, head_height_ratio=head_height_ratio, head_top_range=(top_distance_max, top_distance_min), + face_alignment=face_align, ) except FaceError: result_message = {"status": False} # 如果检测到人脸数量等于1, 则返回标准证和高清照结果(png 4通道图像) else: + result_image_standard_bytes = save_image_dpi_to_bytes(cv2.cvtColor(result.standard, cv2.COLOR_RGBA2BGRA), None, dpi) + result_message = { "status": True, - "image_base64_standard": numpy_2_base64(result.standard), + "image_base64_standard": bytes_2_base64(result_image_standard_bytes), } # 如果hd为True, 则增加高清照结果(png 4通道图像) if hd: - result_message["image_base64_hd"] = numpy_2_base64(result.hd) + result_image_hd_bytes = save_image_dpi_to_bytes(cv2.cvtColor(result.hd, cv2.COLOR_RGBA2BGRA), None, dpi) + result_message["image_base64_hd"] = bytes_2_base64(result_image_hd_bytes) return result_message @@ -92,6 +93,7 @@ async def idphoto_inference( async def human_matting_inference( input_image: UploadFile, human_matting_model: str = Form("hivision_modnet"), + dpi: int = Form(300), ): image_bytes = await input_image.read() nparr = np.frombuffer(image_bytes, np.uint8) @@ -109,9 +111,10 @@ async def human_matting_inference( result_message = {"status": False} else: + result_image_standard_bytes = save_image_dpi_to_bytes(cv2.cvtColor(result.standard, cv2.COLOR_RGBA2BGRA), None, dpi) result_message = { "status": True, - "image_base64": numpy_2_base64(result.standard), + "image_base64": bytes_2_base64(result_image_standard_bytes), } return result_message @@ -122,6 +125,7 @@ async def photo_add_background( input_image: UploadFile, color: str = Form("000000"), kb: int = Form(None), + dpi: int = Form(300), render: int = Form(0), ): render_choice = ["pure_color", "updown_gradient", "center_gradient"] @@ -139,25 +143,17 @@ async def photo_add_background( mode=render_choice[render], ).astype(np.uint8) + result_image = cv2.cvtColor(result_image, cv2.COLOR_RGB2BGR) if kb: - result_image = cv2.cvtColor(result_image, cv2.COLOR_RGB2BGR) - result_image_base64 = resize_image_to_kb_base64(result_image, int(kb)) + result_image_bytes = resize_image_to_kb(result_image, None, int(kb), dpi=dpi) else: - result_image_base64 = numpy_2_base64(result_image) + result_image_bytes = save_image_dpi_to_bytes(result_image, None, dpi=dpi) - # try: result_messgae = { "status": True, - "image_base64": result_image_base64, + "image_base64": bytes_2_base64(result_image_bytes), } - # except Exception as e: - # print(e) - # result_messgae = { - # "status": False, - # "error": e - # } - return result_messgae @@ -168,6 +164,7 @@ async def generate_layout_photos( height: int = Form(413), width: int = Form(295), kb: int = Form(None), + dpi: int = Form(300), ): # try: image_bytes = await input_image.read() @@ -184,24 +181,21 @@ async def generate_layout_photos( img, typography_arr, typography_rotate, height=size[0], width=size[1] ).astype(np.uint8) + result_layout_image = cv2.cvtColor(result_layout_image, cv2.COLOR_RGB2BGR) if kb: - result_layout_image = cv2.cvtColor(result_layout_image, cv2.COLOR_RGB2BGR) - result_layout_image_base64 = resize_image_to_kb_base64( - result_layout_image, int(kb) + result_layout_image_bytes = resize_image_to_kb( + result_layout_image, None, int(kb), dpi=dpi ) else: - result_layout_image_base64 = numpy_2_base64(result_layout_image) + result_layout_image_bytes = save_image_dpi_to_bytes(result_layout_image, None, dpi=dpi) + + result_layout_image_base64 = bytes_2_base64(result_layout_image_bytes) result_messgae = { "status": True, "image_base64": result_layout_image_base64, } - # except Exception as e: - # result_messgae = { - # "status": False, - # } - return result_messgae @@ -216,6 +210,7 @@ async def watermark( color: str = "#000000", space: int = 25, kb: int = Form(None), + dpi: int = Form(300), ): image_bytes = await input_image.read() nparr = np.frombuffer(image_bytes, np.uint8) @@ -224,11 +219,12 @@ async def watermark( try: result_image = add_watermark(img, text, size, opacity, angle, color, space) + result_image = cv2.cvtColor(result_image, cv2.COLOR_RGB2BGR) if kb: - result_image = cv2.cvtColor(result_image, cv2.COLOR_RGB2BGR) - result_image_base64 = resize_image_to_kb_base64(result_image, int(kb)) + result_image_bytes = resize_image_to_kb(result_image, None, int(kb), dpi=dpi) else: - result_image_base64 = numpy_2_base64(result_image) + result_image_bytes = save_image_dpi_to_bytes(result_image, None, dpi=dpi) + result_image_base64 = bytes_2_base64(result_image_bytes) result_messgae = { "status": True, @@ -237,7 +233,7 @@ async def watermark( except Exception as e: result_messgae = { "status": False, - "error": e, + "error": str(e), } return result_messgae @@ -247,6 +243,7 @@ async def watermark( @app.post("/set_kb") async def set_kb( input_image: UploadFile, + dpi: int = Form(300), kb: int = Form(50), ): image_bytes = await input_image.read() @@ -255,7 +252,8 @@ async def set_kb( try: result_image = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - result_image_base64 = resize_image_to_kb_base64(result_image, int(kb)) + result_image_bytes = resize_image_to_kb(result_image, None, int(kb), dpi=dpi) + result_image_base64 = bytes_2_base64(result_image_bytes) result_messgae = { "status": True, @@ -278,6 +276,7 @@ async def idphoto_crop_inference( width: int = Form(295), face_detect_model: str = Form("mtcnn"), hd: bool = Form(True), + dpi: int = Form(300), head_measure_ratio: float = 0.2, head_height_ratio: float = 0.45, top_distance_max: float = 0.12, @@ -305,14 +304,17 @@ async def idphoto_crop_inference( result_message = {"status": False} # 如果检测到人脸数量等于1, 则返回标准证和高清照结果(png 4通道图像) else: + result_image_standard_bytes = save_image_dpi_to_bytes(cv2.cvtColor(result.standard, cv2.COLOR_RGBA2BGRA), None, dpi) + result_message = { "status": True, - "image_base64_standard": numpy_2_base64(result.standard), + "image_base64_standard": bytes_2_base64(result_image_standard_bytes), } # 如果hd为True, 则增加高清照结果(png 4通道图像) if hd: - result_message["image_base64_hd"] = numpy_2_base64(result.hd) + result_image_hd_bytes = save_image_dpi_to_bytes(cv2.cvtColor(result.hd, cv2.COLOR_RGBA2BGRA), None, dpi) + result_message["image_base64_hd"] = bytes_2_base64(result_image_hd_bytes) return result_message diff --git a/docs/api_CN.md b/docs/api_CN.md index 8963d847..414bf9bd 100644 --- a/docs/api_CN.md +++ b/docs/api_CN.md @@ -1,6 +1,6 @@ # API Docs -[English](api_EN.md) / 中文 / [日本語](api_JP.md) / [한국어](api_KO.md) +[English](api_EN.md) / 中文 ## 目录 @@ -9,8 +9,6 @@ - [接口功能说明](#接口功能说明) - [cURL 请求示例](#curl-请求示例) - [Python 请求示例](#python-请求示例) -- [Java 请求示例](#java-请求示例) -- [Javascript 请求示例](#javascript-请求示例) ## 开始之前:开启后端服务 @@ -88,9 +86,11 @@ curl -X POST "http://127.0.0.1:8080/idphoto" \ -F "input_image=@demo/images/test0.jpg" \ -F "height=413" \ -F "width=295" \ --F "human_matting_model=hivision_modnet" \ +-F "human_matting_model=modnet_photographic_portrait_matting" \ -F "face_detect_model=mtcnn" \ --F "hd=true" +-F "hd=true" \ +-F "dpi=300" \ +-F "face_alignment=true" ``` ### 2. 添加背景色 @@ -100,7 +100,8 @@ curl -X POST "http://127.0.0.1:8080/add_background" \ -F "input_image=@test.png" \ -F "color=638cce" \ -F "kb=200" \ --F "render=0" +-F "render=0" \ +-F "dpi=300" ``` ### 3. 生成六寸排版照 @@ -110,7 +111,8 @@ curl -X POST "http://127.0.0.1:8080/generate_layout_photos" \ -F "input_image=@test.jpg" \ -F "height=413" \ -F "width=295" \ --F "kb=200" +-F "kb=200" \ +-F "dpi=300" ``` ### 4. 人像抠图 @@ -118,7 +120,8 @@ curl -X POST "http://127.0.0.1:8080/generate_layout_photos" \ ```bash curl -X POST "http://127.0.0.1:8080/human_matting" \ -F "input_image=@demo/images/test0.jpg" \ --F "human_matting_model=hivision_modnet" +-F "human_matting_model=modnet_photographic_portrait_matting" \ +-F "dpi=300" ``` ### 5. 图片加水印 @@ -128,7 +131,8 @@ curl -X 'POST' \ -H 'accept: application/json' \ -H 'Content-Type: multipart/form-data' \ -F 'input_image=@demo/images/test0.jpg;type=image/jpeg' \ - -F 'text=Hello' + -F 'text=Hello' \ + -F 'dpi=300' ``` ### 6. 设置图像KB大小 @@ -138,7 +142,8 @@ curl -X 'POST' \ -H 'accept: application/json' \ -H 'Content-Type: multipart/form-data' \ -F 'input_image=@demo/images/test0.jpg;type=image/jpeg' \ - -F 'kb=50' + -F 'kb=50' \ + -F 'dpi=300' ``` ### 7. 证件照裁切 @@ -151,7 +156,8 @@ curl -X 'POST' \ -F 'height=413' \ -F 'width=295' \ -F 'face_detect_model=mtcnn' \ - -F 'hd=true' + -F 'hd=true' \ + -F 'dpi=300' ```
@@ -159,21 +165,34 @@ curl -X 'POST' \ ## Python 请求示例 #### 1.生成证件照(底透明) - ```python import requests url = "http://127.0.0.1:8080/idphoto" input_image_path = "demo/images/test0.jpg" +# 设置请求参数 +params = { + "head_measure_ratio": 0.2, + "head_height_ratio": 0.45, + "top_distance_max": 0.12, + "top_distance_min": 0.1, +} files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "human_matting_model": "hivision_modnet", "face_detect_model": "mtcnn", "hd": True} +data = { + "height": 413, + "width": 295, + "human_matting_model": "modnet_photographic_portrait_matting", + "face_detect_model": "mtcnn", + "hd": True, + "dpi": 300, + "face_alignment": True, +} -response = requests.post(url, files=files, data=data).json() +response = requests.post(url, params=params, files=files, data=data).json() # response为一个json格式字典,包含status、image_base64_standard和image_base64_hd三项 print(response) - ``` #### 2.添加背景色 @@ -185,7 +204,12 @@ url = "http://127.0.0.1:8080/add_background" input_image_path = "test.png" files = {"input_image": open(input_image_path, "rb")} -data = {"color": '638cce', "kb": None, "render": 0} +data = { + "color": '638cce', + "kb": None, + "render": 0, + "dpi": 300, +} response = requests.post(url, files=files, data=data).json() @@ -202,7 +226,12 @@ url = "http://127.0.0.1:8080/generate_layout_photos" input_image_path = "test.jpg" files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "kb": 200} +data = { + "height": 413, + "width": 295, + "kb": 200, + "dpi": 300, +} response = requests.post(url, files=files, data=data).json() @@ -219,7 +248,10 @@ url = "http://127.0.0.1:8080/human_matting" input_image_path = "test.jpg" files = {"input_image": open(input_image_path, "rb")} -data = {"human_matting_model": "hivision_modnet"} +data = { + "human_matting_model": "modnet_photographic_portrait_matting", + "dpi": 300, +} response = requests.post(url, files=files, data=data).json() @@ -234,12 +266,18 @@ import requests # 设置请求的 URL 和参数 url = "http://127.0.0.1:8080/watermark" -params = {"size": 20, "opacity": 0.5, "angle": 30, "color": "#000000", "space": 25} +params = { + "size": 20, + "opacity": 0.5, + "angle": 30, + "color": "#000000", + "space": 25, +} # 设置文件和其他表单数据 input_image_path = "demo/images/test0.jpg" files = {"input_image": open(input_image_path, "rb")} -data = {"text": "Hello"} +data = {"text": "Hello", "dpi": 300} # 发送 POST 请求 response = requests.post(url, params=params, files=files, data=data) @@ -264,7 +302,7 @@ url = "http://127.0.0.1:8080/set_kb" # 设置文件和其他表单数据 input_image_path = "demo/images/test0.jpg" files = {"input_image": open(input_image_path, "rb")} -data = {"kb": 50} +data = {"kb": 50, "dpi": 300} # 发送 POST 请求 response = requests.post(url, files=files, data=data) @@ -301,7 +339,8 @@ data = { "height": 413, "width": 295, "face_detect_model": "mtcnn", - "hd": "true" + "hd": "true", + "dpi": 300, } # 发送 POST 请求 @@ -314,292 +353,4 @@ if response.ok: else: # 输出错误信息 print(f"Request failed with status code {response.status_code}: {response.text}") -``` - -
- -## Java 请求示例 - -### 添加 maven 依赖 - -```java - - cn.hutool - hutool-all - 5.8.16 - - - - commons-io - commons-io - 2.6 - -``` - -### 运行代码 - -#### 1.生成证件照(底透明) - -```java -/** -* 生成证件照(底透明) /idphoto 接口 -* @param inputImageDir 文件地址 -* @return -* @throws IOException -*/ -public static String requestIdPhoto(String inputImageDir) throws IOException { - String url = BASE_URL+"/idphoto"; - // 创建文件对象 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - //包含status、image_base64_standard和image_base64_hd三项 - return HttpUtil.post(url, paramMap); -} -``` - -#### 2.添加背景色 - -```java -/** -* 添加背景色 /add_background 接口 -* @param inputImageDir 文件地址 -* @return -* @throws IOException -*/ -public static String requestAddBackground(String inputImageDir) throws IOException { - String url = BASE_URL+"/add_background"; - // 创建文件对象 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("color","638cce"); - paramMap.put("kb","200"); - // response为一个json格式字典,包含status和image_base64 - return HttpUtil.post(url, paramMap); -} -``` - -#### 3.生成六寸排版照 - -```java -/** -* 生成六寸排版照 /generate_layout_photos 接口 -* @param inputImageDir 文件地址 -* @return -* @throws IOException -*/ -public static String requestGenerateLayoutPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/generate_layout_photos"; - // 创建文件对象 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - paramMap.put("kb","200"); - //response为一个json格式字典,包含status和image_base64 - return HttpUtil.post(url, paramMap); -} -``` - -#### 4.人像抠图 - -```java -/** -* 生成人像抠图照 /human_matting 接口 -* @param inputImageDir 文件地址 -* @return -* @throws IOException -*/ -public static String requestHumanMattingPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/human_matting"; - // 创建文件对象 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - //包含status、image_base64 - return HttpUtil.post(url, paramMap); -} -``` - -### 5.图像加水印 - -```java -/** - * 添加水印到图片 /watermark 接口 - * @param inputImageDir 文件地址 - * @param text 水印文本 - * @param size 水印文字大小 - * @param opacity 水印透明度 - * @param angle 水印旋转角度 - * @param color 水印颜色 - * @param space 水印间距 - * @return - * @throws IOException - */ -public static String requestAddWatermark(String inputImageDir, String text, int size, double opacity, int angle, String color, int space) throws IOException { - String url = BASE_URL + "/watermark?size=" + size + "&opacity=" + opacity + "&angle=" + angle + "&color=" + color + "&space=" + space; - - // 创建文件对象 - File inputFile = new File(inputImageDir); - - // 创建参数映射 - Map paramMap = new HashMap<>(); - paramMap.put("input_image", inputFile); - paramMap.put("text", text); - - // 发送POST请求并返回响应 - return HttpUtil.post(url, paramMap); -} -``` - -
- -## JavaScript 请求示例 - -在JavaScript中,我们可以使用`fetch` API来发送HTTP请求。以下是如何使用JavaScript调用这些API的示例。 - -### 1. 生成证件照(底透明) - -```javascript -async function generateIdPhoto(inputImagePath, height, width) { - const url = "http://127.0.0.1:8080/idphoto"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// 示例调用 -generateIdPhoto("images/test.jpg", 413, 295).then(response => { - console.log(response); -}); -``` - -### 2. 添加背景色 - -```javascript -async function addBackground(inputImagePath, color, kb) { - const url = "http://127.0.0.1:8080/add_background"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.png")); - formData.append("color", color); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// 示例调用 -addBackground("test.png", "638cce", 200).then(response => { - console.log(response); -}); -``` - -### 3. 生成六寸排版照 - -```javascript -async function generateLayoutPhotos(inputImagePath, height, width, kb) { - const url = "http://127.0.0.1:8080/generate_layout_photos"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// 示例调用 -generateLayoutPhotos("test.jpg", 413, 295, 200).then(response => { - console.log(response); -}); -``` - -### 4.人像抠图 - -```javascript -async function uploadImage(inputImagePath) { - const url = "http://127.0.0.1:8080/human_matting"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); // 假设响应是JSON格式 - console.log(result); - return result; -} - -// 示例调用 -uploadImage("demo/images/test0.jpg").then(response => { - console.log(response); -}); -``` - -### 5.图像加水印 - -```javascript -async function sendMultipartRequest() { - const url = "http://127.0.0.1:8080/watermark?size=20&opacity=0.5&angle=30&color=%23000000&space=25"; - - const formData = new FormData(); - formData.append("text", "Hello"); - - // Assuming you have a file input element with id 'fileInput' - const fileInput = document.getElementById('fileInput'); - if (fileInput.files.length > 0) { - formData.append("input_image", fileInput.files[0]); - } - - try { - const response = await fetch(url, { - method: 'POST', - headers: { - 'Accept': 'application/json' - }, - body: formData - }); - - if (response.ok) { - const jsonResponse = await response.json(); - console.log(jsonResponse); - } else { - console.error('Request failed:', response.status, response.statusText); - } - } catch (error) { - console.error('Error:', error); - } -} - -// Call the function to send request -sendMultipartRequest(); ``` \ No newline at end of file diff --git a/docs/api_EN.md b/docs/api_EN.md index d28de151..d60797cb 100644 --- a/docs/api_EN.md +++ b/docs/api_EN.md @@ -1,6 +1,6 @@ # API Docs -English / [中文](api_CN.md) / [日本語](api_JP.md) / [한국어](api_KO.md) +English / [中文](README.md) ## Table of Contents @@ -8,8 +8,6 @@ English / [中文](api_CN.md) / [日本語](api_JP.md) / [한국어](api_KO.md) - [API Functionality Description](#api-functionality-description) - [cURL Request Examples](#curl-request-examples) - [Python Request Examples](#python-request-examples) -- [Java Request Examples](#java-request-examples) -- [JavaScript Request Examples](#javascript-request-examples) ## Before You Start: Start the Backend Service @@ -29,37 +27,55 @@ API Name: `idphoto` The logic of the `Generate ID Photo` API is to send an RGB image and output a standard ID photo and a high-definition ID photo: -- **High-Definition ID Photo**: An ID photo created based on the aspect ratio of `size`, with the filename being `output_image_dir` plus `_hd` suffix. -- **Standard ID Photo**: Size equals to `size`, scaled down from the high-definition ID photo, with the filename `output_image_dir`. +- **High-definition ID Photo**: An ID photo created based on the aspect ratio of `size`, with the filename having `_hd` appended to `output_image_dir`. +- **Standard ID Photo**: The size equals `size`, scaled from the high-definition ID photo, with the filename as `output_image_dir`. -It is important to note that both generated photos are transparent (RGBA four-channel images). To generate a complete ID photo, you will also need the `Add Background Color` API below. +It is important to note that both generated photos are transparent (RGBA four-channel images). To create a complete ID photo, you will also need to use the `Add Background Color` API below. > Q: Why is it designed this way? -> A: Because in actual products, users often switch background color previews frequently. Providing a transparent background image for the frontend JS code to synthesize colors is a better user experience. +> A: Because in actual products, users frequently switch background color preview effects, providing a transparent background image for the front-end JS code to composite colors is a better experience. ### 2. Add Background Color API Name: `add_background` -The logic of the `Add Background Color` API is to send an RGBA image and add a background color based on `color`, synthesizing a JPG image. +The logic of the `Add Background Color` API is to receive an RGBA image (transparent image) and add a background color based on `color`, composing a JPG image. -### 3. Generate 6-inch Layout Photo +### 3. Generate Six-Inch Layout Photo API Name: `generate_layout_photos` -The logic of the `Generate 6-inch Layout Photo` API is to send an RGB image (generally the ID photo after adding background color), arrange the photos based on `size`, and then generate a 6-inch layout photo. +The logic of the `Generate Six-Inch Layout Photo` API is to receive an RGB image (usually the ID photo after adding background color), arrange the photos based on `size`, and then generate a six-inch layout photo. ### 4. Human Matting API Name: `human_matting` -The logic of the `Human Matting` API is to send an RGB image and output a standard matting portrait and a high-definition matting portrait (without any background filling). +The logic of the `Human Matting` API is to receive an RGB image and output a standard matting portrait and a high-definition matting portrait (without any background filling). + +### 5. Add Watermark to Image + +API Name: `watermark` + +The functionality of the `Add Watermark to Image` API is to receive a watermark text and add the specified watermark to the original image. Users can specify attributes such as the watermark's position, opacity, and size to seamlessly blend the watermark into the original image. + +### 6. Set Image KB Size + +API Name: `set_kb` + +The functionality of the `Set Image KB Size` API is to receive an image and a target file size (in KB). If the specified KB value is less than the original file, it adjusts the compression rate. If the specified KB value is greater than the source file, it increases the KB value by adding information to the file header, aiming for the final size of the image to match the specified KB value. + +### 7. ID Photo Cropping + +API Name: `idphoto_crop` + +The functionality of the `ID Photo Cropping` API is to receive an RGBA image (transparent image) and output a standard ID photo and a high-definition ID photo.
## cURL Request Examples -cURL is a command-line tool used to transfer data with various network protocols. Below are examples of calling these APIs using cURL. +cURL is a command-line tool for transferring data using various network protocols. Here are examples of using cURL to call these APIs. ### 1. Generate ID Photo (Transparent Background) @@ -68,8 +84,11 @@ curl -X POST "http://127.0.0.1:8080/idphoto" \ -F "input_image=@demo/images/test0.jpg" \ -F "height=413" \ -F "width=295" \ --F "human_matting_model=hivision_modnet" \ --F "face_detect_model=mtcnn" +-F "human_matting_model=modnet_photographic_portrait_matting" \ +-F "face_detect_model=mtcnn" \ +-F "hd=true" \ +-F "dpi=300" \ +-F "face_alignment=true" ``` ### 2. Add Background Color @@ -79,17 +98,19 @@ curl -X POST "http://127.0.0.1:8080/add_background" \ -F "input_image=@test.png" \ -F "color=638cce" \ -F "kb=200" \ --F "render=0" +-F "render=0" \ +-F "dpi=300" ``` -### 3. Generate 6-inch Layout Photo +### 3. Generate Six-Inch Layout Photo ```bash curl -X POST "http://127.0.0.1:8080/generate_layout_photos" \ -F "input_image=@test.jpg" \ -F "height=413" \ -F "width=295" \ --F "kb=200" +-F "kb=200" \ +-F "dpi=300" ``` ### 4. Human Matting @@ -97,7 +118,8 @@ curl -X POST "http://127.0.0.1:8080/generate_layout_photos" \ ```bash curl -X POST "http://127.0.0.1:8080/human_matting" \ -F "input_image=@demo/images/test0.jpg" \ --F "human_matting_model=hivision_modnet" +-F "human_matting_model=modnet_photographic_portrait_matting" \ +-F "dpi=300" ``` ### 5. Add Watermark to Image @@ -107,7 +129,33 @@ curl -X 'POST' \ -H 'accept: application/json' \ -H 'Content-Type: multipart/form-data' \ -F 'input_image=@demo/images/test0.jpg;type=image/jpeg' \ - -F 'text=Hello' + -F 'text=Hello' \ + -F 'dpi=300' +``` + +### 6. Set Image KB Size +```bash +curl -X 'POST' \ + 'http://127.0.0.1:8080/set_kb' \ + -H 'accept: application/json' \ + -H 'Content-Type: multipart/form-data' \ + -F 'input_image=@demo/images/test0.jpg;type=image/jpeg' \ + -F 'kb=50' \ + -F 'dpi=300' +``` + +### 7. ID Photo Cropping +```bash +curl -X 'POST' \ + 'http://127.0.0.1:8080/idphoto_crop?head_measure_ratio=0.2&head_height_ratio=0.45&top_distance_max=0.12&top_distance_min=0.1' \ + -H 'accept: application/json' \ + -H 'Content-Type: multipart/form-data' \ + -F 'input_image=@idphoto_matting.png;type=image/png' \ + -F 'height=413' \ + -F 'width=295' \ + -F 'face_detect_model=mtcnn' \ + -F 'hd=true' \ + -F 'dpi=300' ```
@@ -115,17 +163,31 @@ curl -X 'POST' \ ## Python Request Examples #### 1. Generate ID Photo (Transparent Background) - ```python import requests url = "http://127.0.0.1:8080/idphoto" input_image_path = "demo/images/test0.jpg" +# Set request parameters +params = { + "head_measure_ratio": 0.2, + "head_height_ratio": 0.45, + "top_distance_max": 0.12, + "top_distance_min": 0.1, +} files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "human_matting_model": "hivision_modnet", "face_detect_model": "mtcnn"} +data = { + "height": 413, + "width": 295, + "human_matting_model": "modnet_photographic_portrait_matting", + "face_detect_model": "mtcnn", + "hd": True, + "dpi": 300, + "face_alignment": True, +} -response = requests.post(url, files=files, data=data).json() +response = requests.post(url, params=params, files=files, data=data).json() # response is a JSON formatted dictionary containing status, image_base64_standard, and image_base64_hd print(response) @@ -140,7 +202,12 @@ url = "http://127.0.0.1:8080/add_background" input_image_path = "test.png" files = {"input_image": open(input_image_path, "rb")} -data = {"color": '638cce', "kb": None, "render": 0} +data = { + "color": '638cce', + "kb": None, + "render": 0, + "dpi": 300, +} response = requests.post(url, files=files, data=data).json() @@ -148,7 +215,7 @@ response = requests.post(url, files=files, data=data).json() print(response) ``` -#### 3. Generate 6-inch Layout Photo +#### 3. Generate Six-Inch Layout Photo ```python import requests @@ -157,7 +224,12 @@ url = "http://127.0.0.1:8080/generate_layout_photos" input_image_path = "test.jpg" files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "kb": 200} +data = { + "height": 413, + "width": 295, + "kb": 200, + "dpi": 300, +} response = requests.post(url, files=files, data=data).json() @@ -174,7 +246,10 @@ url = "http://127.0.0.1:8080/human_matting" input_image_path = "test.jpg" files = {"input_image": open(input_image_path, "rb")} -data = {"human_matting_model": "hivision_modnet"} +data = { + "human_matting_model": "modnet_photographic_portrait_matting", + "dpi": 300, +} response = requests.post(url, files=files, data=data).json() @@ -189,309 +264,91 @@ import requests # Set the request URL and parameters url = "http://127.0.0.1:8080/watermark" -params = {"size": 20, "opacity": 0.5, "angle": 30, "color": "#000000", "space": 25} +params = { + "size": 20, + "opacity": 0.5, + "angle": 30, + "color": "#000000", + "space": 25, +} -# Set the file and other form data +# Set file and other form data input_image_path = "demo/images/test0.jpg" files = {"input_image": open(input_image_path, "rb")} -data = {"text": "Hello"} +data = {"text": "Hello", "dpi": 300} # Send POST request response = requests.post(url, params=params, files=files, data=data) -# Check the response +# Check response if response.ok: - # Output the response content + # Output response content print(response.json()) else: - # Output the error information + # Output error message print(f"Request failed with status code {response.status_code}: {response.text}") ``` -
- -## Java Request Examples - -### Add Maven Dependency - -```java - - cn.hutool - hutool-all - 5.8.16 - - - - commons-io - commons-io - 2.6 - -``` - -### Run Code - -#### 1. Generate ID Photo (Transparent Background) - -```java -/** -* Generate ID Photo (Transparent Background) /idphoto API -* @param inputImageDir File path -* @return -* @throws IOException -*/ -public static String requestIdPhoto(String inputImageDir) throws IOException { - String url = BASE_URL+"/idphoto"; - // Create file object - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - // Contains status, image_base64_standard, and image_base64_hd - return HttpUtil.post(url, paramMap); -} -``` - -#### 2. Add Background Color - -```java -/** -* Add Background Color /add_background API -* @param inputImageDir File path -* @return -* @throws IOException -*/ -public static String requestAddBackground(String inputImageDir) throws IOException { - String url = BASE_URL+"/add_background"; - // Create file object - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("color","638cce"); - paramMap.put("kb","200"); - // response is a JSON formatted dictionary containing status and image_base64 - return HttpUtil.post(url, paramMap); -} -``` +### 6. Set Image KB Size -#### 3. Generate 6-inch Layout Photo - -```java -/** -* Generate 6-inch Layout Photo /generate_layout_photos API -* @param inputImageDir File path -* @return -* @throws IOException -*/ -public static String requestGenerateLayoutPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/generate_layout_photos"; - // Create file object - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - paramMap.put("kb","200"); - // response is a JSON formatted dictionary containing status and image_base64 - return HttpUtil.post(url, paramMap); -} -``` - -#### 4. Human Matting - -```java -/** -* Generate Human Matting Photo /human_matting API -* @param inputImageDir File path -* @return -* @throws IOException -*/ -public static String requestHumanMattingPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/human_matting"; - // Create file object - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - // Contains status and image_base64 - return HttpUtil.post(url, paramMap); -} -``` - -### 5. Add Watermark to Image - -```java -/** - * Add watermark to image /watermark API - * @param inputImageDir File path - * @param text Watermark text - * @param size Watermark text size - * @param opacity Watermark opacity - * @param angle Watermark rotation angle - * @param color Watermark color - * @param space Watermark spacing - * @return - * @throws IOException - */ -public static String requestAddWatermark(String inputImageDir, String text, int size, double opacity, int angle, String color, int space) throws IOException { - String url = BASE_URL + "/watermark?size=" + size + "&opacity=" + opacity + "&angle=" + angle + "&color=" + color + "&space=" + space; - - // Create file object - File inputFile = new File(inputImageDir); - - // Create parameter mapping - Map paramMap = new HashMap<>(); - paramMap.put("input_image", inputFile); - paramMap.put("text", text); - - // Send POST request and return response - return HttpUtil.post(url, paramMap); -} -``` - -
- -## JavaScript Request Examples +```python +import requests -In JavaScript, we can use the `fetch` API to send HTTP requests. Below are examples of how to call these APIs using JavaScript. +# Set the request URL +url = "http://127.0.0.1:8080/set_kb" -### 1. Generate ID Photo (Transparent Background) +# Set file and other form data +input_image_path = "demo/images/test0.jpg" +files = {"input_image": open(input_image_path, "rb")} +data = {"kb": 50, "dpi": 300} -```javascript -async function generateIdPhoto(inputImagePath, height, width) { - const url = "http://127.0.0.1:8080/idphoto"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} +# Send POST request +response = requests.post(url, files=files, data=data) -// Example call -generateIdPhoto("images/test.jpg", 413, 295).then(response => { - console.log(response); -}); +# Check response +if response.ok: + # Output response content + print(response.json()) +else: + # Output error message + print(f"Request failed with status code {response.status_code}: {response.text}") ``` -### 2. Add Background Color +### 7. ID Photo Cropping -```javascript -async function addBackground(inputImagePath, color, kb) { - const url = "http://127.0.0.1:8080/add_background"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.png")); - formData.append("color", color); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} +```python +import requests -// Example call -addBackground("test.png", "638cce", 200).then(response => { - console.log(response); -}); -``` +# Set the request URL +url = "http://127.0.0.1:8080/idphoto_crop" -### 3. Generate 6-inch Layout Photo - -```javascript -async function generateLayoutPhotos(inputImagePath, height, width, kb) { - const url = "http://127.0.0.1:8080/generate_layout_photos"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; +# Set request parameters +params = { + "head_measure_ratio": 0.2, + "head_height_ratio": 0.45, + "top_distance_max": 0.12, + "top_distance_min": 0.1, } -// Example call -generateLayoutPhotos("test.jpg", 413, 295, 200).then(response => { - console.log(response); -}); -``` - -### 4. Human Matting - -```javascript -async function uploadImage(inputImagePath) { - const url = "http://127.0.0.1:8080/human_matting"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); // Assuming the response is in JSON format - console.log(result); - return result; +# Set file and other form data +input_image_path = "idphoto_matting.png" +files = {"input_image": ("idphoto_matting.png", open(input_image_path, "rb"), "image/png")} +data = { + "height": 413, + "width": 295, + "face_detect_model": "mtcnn", + "hd": "true", + "dpi": 300, } -// Example call -uploadImage("demo/images/test0.jpg").then(response => { - console.log(response); -}); -``` - -### 5. Add Watermark to Image - -```javascript -async function sendMultipartRequest() { - const url = "http://127.0.0.1:8080/watermark?size=20&opacity=0.5&angle=30&color=%23000000&space=25"; - - const formData = new FormData(); - formData.append("text", "Hello"); - - // Assuming you have a file input element with id 'fileInput' - const fileInput = document.getElementById('fileInput'); - if (fileInput.files.length > 0) { - formData.append("input_image", fileInput.files[0]); - } - - try { - const response = await fetch(url, { - method: 'POST', - headers: { - 'Accept': 'application/json' - }, - body: formData - }); - - if (response.ok) { - const jsonResponse = await response.json(); - console.log(jsonResponse); - } else { - console.error('Request failed:', response.status, response.statusText); - } - } catch (error) { - console.error('Error:', error); - } -} +# Send POST request +response = requests.post(url, params=params, files=files, data=data) -// Call the function to send request -sendMultipartRequest(); +# Check response +if response.ok: + # Output response content + print(response.json()) +else: + # Output error message + print(f"Request failed with status code {response.status_code}: {response.text}") ``` \ No newline at end of file diff --git a/docs/api_JP.md b/docs/api_JP.md deleted file mode 100644 index 7e1aa258..00000000 --- a/docs/api_JP.md +++ /dev/null @@ -1,513 +0,0 @@ -# API Docs - -[English](api_EN.md) / [中文](api_CN.md) / 日本語 / [한국어](api_KO.md) - -## 目次 - -- [始める前に:バックエンドサービスを起動する](#始める前にバックエンドサービスを起動する) -- [インターフェース機能説明](#インターフェース機能説明) -- [cURL リクエスト例](#curl-リクエスト例) -- [Python リクエスト例](#python-リクエスト例) - - [Python Requests リクエスト方法](#1️⃣-python-requests-リクエスト方法) - - [Python スクリプトリクエスト方法](#2️⃣-python-スクリプトリクエスト方法) -- [Java リクエスト例](#java-リクエスト例) -- [Javascript リクエスト例](#javascript-リクエスト例) - -## 始める前に:バックエンドサービスを起動する - -API をリクエストする前に、バックエンドサービスを実行してください。 - -```bash -python deploy_api.py -``` - -
- -## インターフェース機能説明 - -### 1.証明写真を生成する(透明な背景) - -インターフェース名:`idphoto` - -`証明写真を生成する`インターフェースのロジックは、RGB画像を送信し、標準の証明写真と高解像度の証明写真を出力します: - -- **高解像度の証明写真**:`size`のアスペクト比に基づいて作成された証明写真で、ファイル名は`output_image_dir`に`_hd`という接尾辞が追加されます。 -- **標準の証明写真**:サイズは`size`と等しく、高解像度の証明写真からスケーリングされ、ファイル名は`output_image_dir`です。 - -生成される2枚の写真はどちらも透明です(RGBA 4チャンネル画像)ので、完全な証明写真を生成するには、以下の`背景色を追加する`インターフェースが必要です。 - -> 質問:なぜこのように設計されているのですか? -> 答え:実際の製品では、ユーザーが頻繁に背景色を切り替えてプレビュー効果を確認するため、透明な背景画像を直接提供し、フロントエンドのjsコードで色を合成する方がより良い体験となります。 - -### 2.背景色を追加する - -インターフェース名:`add_background` - -`背景色を追加する`インターフェースのロジックは、RGBA画像を送信し、`color`に基づいて背景色を追加し、JPG画像を合成します。 - -### 3.六寸レイアウト写真を生成する - -インターフェース名:`generate_layout_photos` - -`六寸レイアウト写真を生成する`インターフェースのロジックは、RGB画像(一般的には背景色を追加した後の証明写真)を送信し、`size`に基づいて写真を配置し、六寸レイアウト写真を生成します。 - -### 4.人物切り抜き - -インターフェース名:`human_matting` - -`人物切り抜き`インターフェースのロジックは、RGB画像を送信し、標準の切り抜き人物写真と高解像度の切り抜き人物写真(背景が何も填充されていない)を出力します。 - -
- -## cURL リクエスト例 - -cURLは、さまざまなネットワークプロトコルを使用してデータを転送するためのコマンドラインツールです。以下は、cURLを使用してこれらのAPIを呼び出す例です。 - -### 1. 証明写真を生成する(透明な背景) - -```bash -curl -X POST "http://127.0.0.1:8080/idphoto" \ --F "input_image=@demo/images/test0.jpg" \ --F "height=413" \ --F "width=295" \ --F "human_matting_model=hivision_modnet" \ --F "face_detect_model=mtcnn" -``` - -### 2. 背景色を追加する - -```bash -curl -X POST "http://127.0.0.1:8080/add_background" \ --F "input_image=@test.png" \ --F "color=638cce" \ --F "kb=200" \ --F "render=0" -``` - -### 3. 六寸レイアウト写真を生成する - -```bash -curl -X POST "http://127.0.0.1:8080/generate_layout_photos" \ --F "input_image=@test.jpg" \ --F "height=413" \ --F "width=295" \ --F "kb=200" -``` - -### 4. 人物切り抜き - -```bash -curl -X POST "http://127.0.0.1:8080/human_matting" \ --F "input_image=@demo/images/test0.jpg" \ --F "human_matting_model=hivision_modnet" -``` - -
- -## Python リクエスト例 - -### 1️⃣ Python Requests リクエスト方法 - -#### 1.証明写真を生成する(透明な背景) - -```python -import requests - -url = "http://127.0.0.1:8080/idphoto" -input_image_path = "images/test0.jpg" - -files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "human_matting_model": "hivision_modnet", "face_detect_model": "mtcnn"} - -response = requests.post(url, files=files, data=data).json() - -# responseはjson形式の辞書で、status、image_base64_standard、image_base64_hdの3項目を含みます -print(response) - -``` - -#### 2.背景色を追加する - -```python -import requests - -url = "http://127.0.0.1:8080/add_background" -input_image_path = "test.png" - -files = {"input_image": open(input_image_path, "rb")} -data = {"color": '638cce', "kb": None, "render": 0} - -response = requests.post(url, files=files, data=data).json() - -# responseはjson形式の辞書で、statusとimage_base64を含みます -print(response) -``` - -#### 3.六寸レイアウト写真を生成する - -```python -import requests - -url = "http://127.0.0.1:8080/generate_layout_photos" -input_image_path = "test.jpg" - -files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "kb": 200} - -response = requests.post(url, files=files, data=data).json() - -# responseはjson形式の辞書で、statusとimage_base64を含みます -print(response) -``` - -#### 4.人物切り抜き - -```python -import requests - -url = "http://127.0.0.1:8080/human_matting" -input_image_path = "test.jpg" - -files = {"input_image": open(input_image_path, "rb")} -data = {"human_matting_model": "hivision_modnet"} - -response = requests.post(url, files=files, data=data).json() - -# responseはjson形式の辞書で、statusとimage_base64を含みます -print(response) -``` - -### 2️⃣ Python スクリプトリクエスト方法 - -```bash -python requests_api.py -u -t -i -o [--height ] [--width ] [-c ] [-k ] -``` - -#### パラメータ説明 - -##### 基本パラメータ - -- `-u`, `--url` - - - **説明**: APIサービスのURL。 - - **デフォルト値**: `http://127.0.0.1:8080` - -- `-t`, `--type` - - - **説明**: APIをリクエストする種類。 - - **デフォルト値**: `idphoto` - -- `-i`, `--input_image_dir` - - - **説明**: 入力画像のパス。 - - **必須**: はい - - **例**: `./input_images/photo.jpg` - -- `-o`, `--output_image_dir` - - **説明**: 画像の保存パス。 - - **必須**: はい - - **例**: `./output_images/processed_photo.jpg` - -##### オプションパラメータ - -- `--face_detect_model` - - **説明**: 顔検出モデル - - **デフォルト値**: mtcnn - -- `--human_matting_model` - - **説明**: 人物切り抜きモデル - - **デフォルト値**: hivision_modnet - -- `--height`, - - **説明**: 標準証明写真の出力サイズの高さ。 - - **デフォルト値**: 413 - -- `--width`, - - **説明**: 標準証明写真の出力サイズの幅。 - - **デフォルト値**: 295 - -- `-c`, `--color` - - **説明**: 透明画像に背景色を追加する、形式はHex(例:#638cce)、typeが`add_background`のときのみ有効 - - **デフォルト値**: `638cce` - -- `-k`, `--kb` - - **説明**: 出力写真のKB値、typeが`add_background`と`generate_layout_photos`のときのみ有効、値がNoneのときは設定しません。 - - **デフォルト値**: `None` - - **例**: 50 - -- `-r`, `--render` - - **説明**: 透明画像に背景色を追加する際のレンダリング方式、typeが`add_background`と`generate_layout_photos`のときのみ有効 - - **デフォルト値**: 0 - -### 1.証明写真を生成する(透明な背景) - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t idphoto \ - -i ./photo.jpg \ - -o ./idphoto.png \ - --height 413 \ - --width 295 \ - --face_detect_model mtcnn \ - --human_matting_model hivision_modnet -``` - -### 2.背景色を追加する - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t add_background \ - -i ./idphoto.png \ - -o ./idphoto_with_background.jpg \ - -c 638cce \ - -k 50 \ - -r 0 -``` - -### 3.六寸レイアウト写真を生成する - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t generate_layout_photos \ - -i ./idphoto_with_background.jpg \ - -o ./layout_photo.jpg \ - --height 413 \ - --width 295 \ - -k 200 -``` - -### 4.人物切り抜き - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t human_matting \ - -i ./photo.jpg \ - -o ./photo_matting.png \ - --human_matting_model hivision_modnet -``` - -### リクエスト失敗の状況 - -- 写真に検出された顔が1つを超える場合、失敗します。 - -
- -## Java リクエスト例 - -### Maven依存関係を追加 - -```java - - cn.hutool - hutool-all - 5.8.16 - - - - commons-io - commons-io - 2.6 - -``` - -### コードを実行する - -#### 1.証明写真を生成する(透明な背景) - -```java -/** - * 証明写真を生成する(透明な背景) /idphoto インターフェース - * @param inputImageDir ファイルのパス - * @return - * @throws IOException - */ -public static String requestIdPhoto(String inputImageDir) throws IOException { - String url = BASE_URL+"/idphoto"; - // ファイルオブジェクトを作成 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - // status、image_base64_standard、image_base64_hdの3項目を含みます - return HttpUtil.post(url, paramMap); -} -``` - -#### 2.背景色を追加する - -```java -/** - * 背景色を追加する /add_background インターフェース - * @param inputImageDir ファイルのパス - * @return - * @throws IOException - */ -public static String requestAddBackground(String inputImageDir) throws IOException { - String url = BASE_URL+"/add_background"; - // ファイルオブジェクトを作成 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("color","638cce"); - paramMap.put("kb","200"); - // responseはjson形式の辞書で、statusとimage_base64を含みます - return HttpUtil.post(url, paramMap); -} -``` - -#### 3.六寸レイアウト写真を生成する - -```java -/** - * 六寸レイアウト写真を生成する /generate_layout_photos インターフェース - * @param inputImageDir ファイルのパス - * @return - * @throws IOException - */ -public static String requestGenerateLayoutPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/generate_layout_photos"; - // ファイルオブジェクトを作成 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - paramMap.put("kb","200"); - // responseはjson形式の辞書で、statusとimage_base64を含みます - return HttpUtil.post(url, paramMap); -} -``` - -#### 4.人物切り抜き - -```java -/** - * 人物切り抜き写真を生成する /human_matting インターフェース - * @param inputImageDir ファイルのパス - * @return - * @throws IOException - */ -public static String requestHumanMattingPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/human_matting"; - // ファイルオブジェクトを作成 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - // status、image_base64を含みます - return HttpUtil.post(url, paramMap); -} -``` - -
- -## JavaScript リクエスト例 - -JavaScriptでは、`fetch` APIを使用してHTTPリクエストを送信できます。以下は、JavaScriptでこれらのAPIを呼び出す方法の例です。 - -### 1. 証明写真を生成する(透明な背景) - -```javascript -async function generateIdPhoto(inputImagePath, height, width) { - const url = "http://127.0.0.1:8080/idphoto"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// サンプル呼び出し -generateIdPhoto("images/test0.jpg", 413, 295).then(response => { - console.log(response); -}); -``` - -### 2. 背景色を追加する - -```javascript -async function addBackground(inputImagePath, color, kb) { - const url = "http://127.0.0.1:8080/add_background"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.png")); - formData.append("color", color); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// サンプル呼び出し -addBackground("test.png", "638cce", 200).then(response => { - console.log(response); -}); -``` - -### 3. 六寸レイアウト写真を生成する - -```javascript -async function generateLayoutPhotos(inputImagePath, height, width, kb) { - const url = "http://127.0.0.1:8080/generate_layout_photos"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// サンプル呼び出し -generateLayoutPhotos("test.jpg", 413, 295, 200).then(response => { - console.log(response); -}); -``` - -### 4. 人物切り抜き - -```javascript -async function uploadImage(inputImagePath) { - const url = "http://127.0.0.1:8080/human_matting"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); // 応答がJSON形式であると仮定 - console.log(result); - return result; -} - -// サンプル呼び出し -uploadImage("demo/images/test0.jpg").then(response => { - console.log(response); -}); -``` \ No newline at end of file diff --git a/docs/api_KO.md b/docs/api_KO.md deleted file mode 100644 index 3edb91df..00000000 --- a/docs/api_KO.md +++ /dev/null @@ -1,515 +0,0 @@ -# API 문서 - -[English](api_EN.md) / [中文](api_CN.md) / [日本語](api_JP.md) / 한국어 - - -## 목차 - -- [시작하기: 백엔드 서비스 시작하기](#시작하기-백엔드-서비스-시작하기) -- [인터페이스 기능 설명](#인터페이스-기능-설명) -- [cURL 요청 예시](#curl-요청-예시) -- [Python 요청 예시](#python-요청-예시) - - [Python Requests 요청 방법](#1️⃣-python-requests-요청-방법) - - [Python 스크립트 요청 방법](#2️⃣-python-스크립트-요청-방법) -- [Java 요청 예시](#java-요청-예시) -- [JavaScript 요청 예시](#javascript-요청-예시) - -## 시작하기: 백엔드 서비스 시작하기 - -API를 요청하기 전에 백엔드 서비스를 먼저 실행하세요. - -```bash -python deploy_api.py -``` - -
- -## 인터페이스 기능 설명 - -### 1. 증명사진 생성(투명 배경) - -인터페이스 이름: `idphoto` - -`증명사진 생성` 인터페이스의 논리는 RGB 이미지를 전송하고 표준 증명사진과 고해상도 증명사진을 출력하는 것입니다: - -- **고해상도 증명사진**: `size`의 가로 세로 비율에 따라 제작된 증명사진, 파일 이름은 `output_image_dir`에 `_hd` 접미사를 추가한 것입니다. -- **표준 증명사진**: 크기가 `size`와 같으며, 고해상도 증명사진에서 축소된 것입니다, 파일 이름은 `output_image_dir`입니다. - -생성된 두 장의 사진은 모두 투명합니다(RGBA 4채널 이미지), 완전한 증명사진을 생성하려면 아래의 `배경색 추가` 인터페이스가 필요합니다. - -> 질문: 왜 이렇게 디자인했나요? -> 답변: 실제 제품에서는 사용자가 배경색 미리보기를 자주 변경하므로, 투명 배경 이미지를 제공하고 프론트엔드 js 코드로 색상을 합성하는 것이 더 나은 경험을 제공합니다. - -### 2. 배경색 추가 - -인터페이스 이름: `add_background` - -`배경색 추가` 인터페이스의 논리는 RGBA 이미지를 전송하고 `color`에 따라 배경색을 추가하여 JPG 이미지를 합성하는 것입니다. - -### 3. 6인치 레이아웃 사진 생성 - -인터페이스 이름: `generate_layout_photos` - -`6인치 레이아웃 사진 생성` 인터페이스의 논리는 RGB 이미지를 전송하고(일반적으로 배경색 추가 후의 증명사진), `size`에 따라 사진을 배치한 다음 6인치 레이아웃 사진을 생성하는 것입니다. - -### 4. 인물 추출 - -인터페이스 이름: `human_matting` - -`인물 추출` 인터페이스의 논리는 RGB 이미지를 전송하고 표준 인물 사진과 고해상도 인물 사진(배경이 없는)을 출력하는 것입니다. - -
- -## cURL 요청 예시 - -cURL은 다양한 네트워크 프로토콜을 사용하여 데이터를 전송하는 명령줄 도구입니다. 다음은 cURL을 사용하여 이 API를 호출하는 예시입니다. - -### 1. 증명사진 생성(투명 배경) - -```bash -curl -X POST "http://127.0.0.1:8080/idphoto" \ --F "input_image=@demo/images/test0.jpg" \ --F "height=413" \ --F "width=295" \ --F "human_matting_model=hivision_modnet" \ --F "face_detect_model=mtcnn" -``` - -### 2. 배경색 추가 - -```bash -curl -X POST "http://127.0.0.1:8080/add_background" \ --F "input_image=@test.png" \ --F "color=638cce" \ --F "kb=200" \ --F "render=0" -``` - -### 3. 6인치 레이아웃 사진 생성 - -```bash -curl -X POST "http://127.0.0.1:8080/generate_layout_photos" \ --F "input_image=@test.jpg" \ --F "height=413" \ --F "width=295" \ --F "kb=200" -``` - -### 4. 인물 추출 - -```bash -curl -X POST "http://127.0.0.1:8080/human_matting" \ --F "input_image=@demo/images/test0.jpg" \ --F "human_matting_model=hivision_modnet" -``` - -
- -## Python 요청 예시 - -### 1️⃣ Python Requests 요청 방법 - -#### 1. 증명사진 생성(투명 배경) - -```python -import requests - -url = "http://127.0.0.1:8080/idphoto" -input_image_path = "images/test0.jpg" - -files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "human_matting_model": "hivision_modnet", "face_detect_model": "mtcnn"} - -response = requests.post(url, files=files, data=data).json() - -# response는 status, image_base64_standard 및 image_base64_hd를 포함하는 JSON 형식의 사전입니다. -print(response) - -``` - -#### 2. 배경색 추가 - -```python -import requests - -url = "http://127.0.0.1:8080/add_background" -input_image_path = "test.png" - -files = {"input_image": open(input_image_path, "rb")} -data = {"color": '638cce', "kb": None, "render": 0} - -response = requests.post(url, files=files, data=data).json() - -# response는 status와 image_base64를 포함하는 JSON 형식의 사전입니다. -print(response) -``` - -#### 3. 6인치 레이아웃 사진 생성 - -```python -import requests - -url = "http://127.0.0.1:8080/generate_layout_photos" -input_image_path = "test.jpg" - -files = {"input_image": open(input_image_path, "rb")} -data = {"height": 413, "width": 295, "kb": 200} - -response = requests.post(url, files=files, data=data).json() - -# response는 status와 image_base64를 포함하는 JSON 형식의 사전입니다. -print(response) -``` - -#### 4. 인물 추출 - -```python -import requests - -url = "http://127.0.0.1:8080/human_matting" -input_image_path = "test.jpg" - -files = {"input_image": open(input_image_path, "rb")} -data = {"human_matting_model": "hivision_modnet"} - -response = requests.post(url, files=files, data=data).json() - -# response는 status와 image_base64를 포함하는 JSON 형식의 사전입니다. -print(response) -``` - -### 2️⃣ Python 스크립트 요청 방법 - -```bash -python requests_api.py -u -t -i -o [--height ] [--width ] [-c ] [-k ] -``` - -#### 매개변수 설명 - -##### 기본 매개변수 - -- `-u`, `--url` - - - **설명**: API 서비스의 URL입니다. - - **기본값**: `http://127.0.0.1:8080` - -- `-t`, `--type` - - - **설명**: 요청 API의 종류입니다. - - **기본값**: `idphoto` - -- `-i`, `--input_image_dir` - - - **설명**: 입력 이미지 경로입니다. - - **필수**: 예 - - **예시**: `./input_images/photo.jpg` - -- `-o`, `--output_image_dir` - - **설명**: 저장 이미지 경로입니다. - - **필수**: 예 - - **예시**: `./output_images/processed_photo.jpg` - -##### 선택적 매개변수 - -- `--face_detect_model` - - **설명**: 얼굴 인식 모델입니다. - - **기본값**: mtcnn - -- `--human_matting_model` - - **설명**: 인물 추출 모델입니다. - - **기본값**: hivision_modnet - -- `--height` - - **설명**: 표준 증명사진의 출력 사이즈 높이입니다. - - **기본값**: 413 - -- `--width` - - **설명**: 표준 증명사진의 출력 사이즈 너비입니다. - - **기본값**: 295 - -- `-c`, `--color` - - **설명**: 투명 이미지에 배경색을 추가합니다, 형식은 Hex(#638cce)입니다, type이 `add_background`일 때만 유효합니다. - - **기본값**: `638cce` - -- `-k`, `--kb` - - **설명**: 출력 사진의 KB 값입니다, type이 `add_background`와 `generate_layout_photos`일 때만 유효하며, 값이 None일 때는 설정하지 않습니다. - - **기본값**: `None` - - **예시**: 50 - -- `-r`, `--render` - - **설명**: 투명 이미지에 배경색을 추가할 때의 렌더링 방식입니다, type이 `add_background`와 `generate_layout_photos`일 때만 유효합니다. - - **기본값**: 0 - -### 1. 증명사진 생성(투명 배경) - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t idphoto \ - -i ./photo.jpg \ - -o ./idphoto.png \ - --height 413 \ - --width 295 \ - --face_detect_model mtcnn \ - --human_matting_model hivision_modnet -``` - -### 2. 배경색 추가 - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t add_background \ - -i ./idphoto.png \ - -o ./idphoto_with_background.jpg \ - -c 638cce \ - -k 50 \ - -r 0 -``` - -### 3. 6인치 레이아웃 사진 생성 - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t generate_layout_photos \ - -i ./idphoto_with_background.jpg \ - -o ./layout_photo.jpg \ - --height 413 \ - --width 295 \ - -k 200 -``` - - -### 4. 인물 추출 - -```bash -python requests_api.py \ - -u http://127.0.0.1:8080 \ - -t human_matting \ - -i ./photo.jpg \ - -o ./photo_matting.png \ - --human_matting_model hivision_modnet -``` - -### 요청 실패의 경우 - -- 사진에서 감지된 얼굴이 1개 이상일 경우 실패합니다. - -
- -## Java 요청 예시 - -### Maven 의존성 추가 - -```java - - cn.hutool - hutool-all - 5.8.16 - - - - commons-io - commons-io - 2.6 - -``` - -### 코드 실행 - -#### 1. 증명사진 생성(투명 배경) - -```java -/** - * 증명사진 생성(투명 배경) /idphoto 인터페이스 - * @param inputImageDir 파일 주소 - * @return - * @throws IOException - */ -public static String requestIdPhoto(String inputImageDir) throws IOException { - String url = BASE_URL+"/idphoto"; - // 파일 객체 생성 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - // status, image_base64_standard 및 image_base64_hd를 포함합니다. - return HttpUtil.post(url, paramMap); -} -``` - -#### 2. 배경색 추가 - -```java -/** - * 배경색 추가 /add_background 인터페이스 - * @param inputImageDir 파일 주소 - * @return - * @throws IOException - */ -public static String requestAddBackground(String inputImageDir) throws IOException { - String url = BASE_URL+"/add_background"; - // 파일 객체 생성 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("color","638cce"); - paramMap.put("kb","200"); - // response는 status와 image_base64를 포함하는 JSON 형식의 사전입니다. - return HttpUtil.post(url, paramMap); -} -``` - -#### 3. 6인치 레이아웃 사진 생성 - -```java -/** - * 6인치 레이아웃 사진 생성 /generate_layout_photos 인터페이스 - * @param inputImageDir 파일 주소 - * @return - * @throws IOException - */ -public static String requestGenerateLayoutPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/generate_layout_photos"; - // 파일 객체 생성 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - paramMap.put("height","413"); - paramMap.put("width","295"); - paramMap.put("kb","200"); - // response는 status와 image_base64를 포함하는 JSON 형식의 사전입니다. - return HttpUtil.post(url, paramMap); -} -``` - -#### 4. 인물 추출 - -```java -/** - * 인물 추출 사진 생성 /human_matting 인터페이스 - * @param inputImageDir 파일 주소 - * @return - * @throws IOException - */ -public static String requestHumanMattingPhotos(String inputImageDir) throws IOException { - String url = BASE_URL+"/human_matting"; - // 파일 객체 생성 - File inputFile = new File(inputImageDir); - Map paramMap=new HashMap<>(); - paramMap.put("input_image",inputFile); - // status와 image_base64를 포함합니다. - return HttpUtil.post(url, paramMap); -} -``` - -
- -## JavaScript 요청 예시 - -JavaScript에서는 `fetch` API를 사용하여 HTTP 요청을 보낼 수 있습니다. 다음은 JavaScript를 사용하여 이 API를 호출하는 예시입니다. - -### 1. 증명사진 생성(투명 배경) - -```javascript -async function generateIdPhoto(inputImagePath, height, width) { - const url = "http://127.0.0.1:8080/idphoto"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// 예시 호출 -generateIdPhoto("images/test0.jpg", 413, 295).then(response => { - console.log(response); -}); -``` - -### 2. 배경색 추가 - -```javascript -async function addBackground(inputImagePath, color, kb) { - const url = "http://127.0.0.1:8080/add_background"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.png")); - formData.append("color", color); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// 예시 호출 -addBackground("test.png", "638cce", 200).then(response => { - console.log(response); -}); -``` - -### 3. 6인치 레이아웃 사진 생성 - -```javascript -async function generateLayoutPhotos(inputImagePath, height, width, kb) { - const url = "http://127.0.0.1:8080/generate_layout_photos"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - formData.append("height", height); - formData.append("width", width); - formData.append("kb", kb); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); - console.log(result); - return result; -} - -// 예시 호출 -generateLayoutPhotos("test.jpg", 413, 295, 200).then(response => { - console.log(response); -}); -``` - -### 4. 인물 추출 - -```javascript -async function uploadImage(inputImagePath) { - const url = "http://127.0.0.1:8080/human_matting"; - const formData = new FormData(); - formData.append("input_image", new File([await fetch(inputImagePath).then(res => res.blob())], "test.jpg")); - - const response = await fetch(url, { - method: 'POST', - body: formData - }); - - const result = await response.json(); // 응답이 JSON 형식이라고 가정합니다. - console.log(result); - return result; -} - -// 예시 호출 -uploadImage("demo/images/test0.jpg").then(response => { - console.log(response); -}); -``` \ No newline at end of file diff --git a/hivision/utils.py b/hivision/utils.py index 0a862186..f73a17f7 100644 --- a/hivision/utils.py +++ b/hivision/utils.py @@ -8,7 +8,7 @@ from hivision.plugin.watermark import Watermarker, WatermarkerStyles -def save_image_dpi_to_bytes(image, output_image_path, dpi=300): +def save_image_dpi_to_bytes(image: np.ndarray, output_image_path: str = None, dpi: int = 300): """ 设置图像的DPI(每英寸点数)并返回字节流 @@ -25,13 +25,14 @@ def save_image_dpi_to_bytes(image, output_image_path, dpi=300): image_bytes = byte_stream.getvalue() # Save the image to the output path - with open(output_image_path, "wb") as f: - f.write(image_bytes) + if output_image_path: + with open(output_image_path, "wb") as f: + f.write(image_bytes) return image_bytes -def resize_image_to_kb(input_image, output_image_path, target_size_kb, dpi=300): +def resize_image_to_kb(input_image: np.ndarray, output_image_path: str = None, target_size_kb: int = 100, dpi: int = 300): """ Resize an image to a target size in KB. 将图像调整大小至目标文件大小(KB)。 @@ -79,9 +80,11 @@ def resize_image_to_kb(input_image, output_image_path, target_size_kb, dpi=300): img_byte_arr.write(padding) # Save the image to the output path - with open(output_image_path, "wb") as f: - f.write(img_byte_arr.getvalue()) - break + if output_image_path: + with open(output_image_path, "wb") as f: + f.write(img_byte_arr.getvalue()) + + return img_byte_arr.getvalue() # Reduce the quality if the image is still too large quality -= 5 @@ -177,6 +180,11 @@ def base64_2_numpy(base64_image: str) -> np.ndarray: return img +# 字节流转base64 +def bytes_2_base64(img_byte_arr: bytes) -> str: + base64_image = base64.b64encode(img_byte_arr).decode("utf-8") + return "data:image/png;base64," + base64_image + def save_numpy_image(numpy_img, file_path): # 检查数组的形状 diff --git a/inference.py b/inference.py index 8021b331..95e5c5cd 100644 --- a/inference.py +++ b/inference.py @@ -3,7 +3,7 @@ import argparse import numpy as np from hivision.error import FaceError -from hivision.utils import hex_to_rgb, resize_image_to_kb, add_background +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, @@ -18,7 +18,6 @@ "human_matting", "add_background", "generate_layout_photos", - "watermark", "idphoto_crop", ] MATTING_MODEL = [ @@ -48,15 +47,10 @@ parser.add_argument("--height", help="证件照尺寸-高", default=413) parser.add_argument("--width", help="证件照尺寸-宽", default=295) parser.add_argument("-c", "--color", help="证件照背景色", default="638cce") +parser.add_argument("--hd", type=bool, help="是否输出高清照", default=True) parser.add_argument( "-k", "--kb", help="输出照片的 KB 值,仅对换底和制作排版照生效", default=None ) -parser.add_argument( - "--matting_model", - help="抠图模型权重", - default="hivision_modnet", - choices=MATTING_MODEL, -) parser.add_argument( "-r", "--render", @@ -65,6 +59,24 @@ choices=RENDER, default=0, ) +parser.add_argument( + "--dpi", + type=int, + help="输出照片的 DPI 值", + default=300, +) +parser.add_argument( + "--face_align", + type=bool, + help="是否进行人脸旋转矫正", + default=False, +) +parser.add_argument( + "--matting_model", + help="抠图模型权重", + default="modnet_photographic_portrait_matting", + choices=MATTING_MODEL, +) parser.add_argument( "--face_detect_model", help="人脸检测模型", @@ -86,17 +98,17 @@ # 将字符串转为元组 size = (int(args.height), int(args.width)) try: - result = creator(input_image, size=size) + result = creator(input_image, size=size, face_alignment=args.face_align) except FaceError: print("人脸数量不等于 1,请上传单张人脸的图像。") else: # 保存标准照 - cv2.imwrite(args.output_image_dir, result.standard) + save_image_dpi_to_bytes(cv2.cvtColor(result.standard, cv2.COLOR_RGBA2BGRA), args.output_image_dir, dpi=args.dpi) # 保存高清照 file_name, file_extension = os.path.splitext(args.output_image_dir) new_file_name = file_name + "_hd" + file_extension - cv2.imwrite(new_file_name, result.hd) + save_image_dpi_to_bytes(cv2.cvtColor(result.hd, cv2.COLOR_RGBA2BGRA), new_file_name, dpi=args.dpi) # 如果模式是人像抠图 elif args.type == "human_matting": @@ -117,14 +129,12 @@ input_image, bgr=color, mode=render_choice[args.render] ) result_image = result_image.astype(np.uint8) - + result_image = cv2.cvtColor(result_image, cv2.COLOR_RGBA2BGRA) + if args.kb: - result_image = cv2.cvtColor(result_image, cv2.COLOR_RGB2BGR) - result_image = resize_image_to_kb( - result_image, args.output_image_dir, int(args.kb) - ) + resize_image_to_kb(result_image, args.output_image_dir, int(args.kb), dpi=args.dpi) else: - cv2.imwrite(args.output_image_dir, result_image) + save_image_dpi_to_bytes(cv2.cvtColor(result_image, cv2.COLOR_RGBA2BGRA), args.output_image_dir, dpi=args.dpi) # 如果模式是生成排版照 elif args.type == "generate_layout_photos": @@ -146,10 +156,10 @@ if args.kb: result_layout_image = cv2.cvtColor(result_layout_image, cv2.COLOR_RGB2BGR) result_layout_image = resize_image_to_kb( - result_layout_image, args.output_image_dir, int(args.kb) + result_layout_image, args.output_image_dir, int(args.kb), dpi=args.dpi ) else: - cv2.imwrite(args.output_image_dir, result_layout_image) + save_image_dpi_to_bytes(cv2.cvtColor(result_layout_image, cv2.COLOR_RGBA2BGRA), args.output_image_dir, dpi=args.dpi) # 如果模式是证件照裁切 elif args.type == "idphoto_crop": @@ -161,9 +171,9 @@ print("人脸数量不等于 1,请上传单张人脸的图像。") else: # 保存标准照 - cv2.imwrite(args.output_image_dir, result.standard) + save_image_dpi_to_bytes(cv2.cvtColor(result.standard, cv2.COLOR_RGBA2BGRA), args.output_image_dir, dpi=args.dpi) # 保存高清照 file_name, file_extension = os.path.splitext(args.output_image_dir) new_file_name = file_name + "_hd" + file_extension - cv2.imwrite(new_file_name, result.hd) + save_image_dpi_to_bytes(cv2.cvtColor(result.hd, cv2.COLOR_RGBA2BGRA), new_file_name, dpi=args.dpi) \ No newline at end of file