longshiine commited on
Commit
656c922
·
1 Parent(s): a68b775

feat: 제품 이미지 사이즈 조절 추가

Browse files

Signed-off-by: longshiine <[email protected]>

Files changed (3) hide show
  1. .gitignore +2 -1
  2. app.py +5 -3
  3. infra.py +40 -63
.gitignore CHANGED
@@ -1 +1,2 @@
1
- __pycache__/
 
 
1
+ __pycache__/
2
+ .DS_Store
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import gradio as gr
2
  from infra import image_processing_single, image_processing_batch
3
 
4
- with gr.Blocks(theme='NoCrypt/miku', title='Image Generator') as demo:
5
  gr.HTML("""
6
  <h1>Product Image Generator</h1>
7
  <p>1. 배경 이미지를 업로드해주세요.<p>
@@ -19,6 +19,7 @@ with gr.Blocks(theme='NoCrypt/miku', title='Image Generator') as demo:
19
  label="예제 배경 이미지")
20
  with gr.Tab("Single Mode"):
21
  with gr.Column():
 
22
  link = gr.Textbox(label="Image URL")
23
  gr.Examples(
24
  examples=["https://url.kr/yx85be", "https://url.kr/if4wxo"],
@@ -30,6 +31,7 @@ with gr.Blocks(theme='NoCrypt/miku', title='Image Generator') as demo:
30
  gr.HTML("<div>링크1(엔터) 링크2(엔터) ... 으로 구성된 .txt 파일을 업로드</div>")
31
  with gr.Column():
32
  links = gr.File(label="Image URLs (.txt file)", height=100)
 
33
  gr.Examples(
34
  examples=[["examples/links.txt"]],
35
  inputs=links,
@@ -50,7 +52,7 @@ with gr.Blocks(theme='NoCrypt/miku', title='Image Generator') as demo:
50
  output_zip = gr.File(label="Download Result Zip File")
51
 
52
  # evnets
53
- btn_single.click(fn=image_processing_single, inputs=[background_image, link], outputs=[preview, output_zip], api_name="image_processing_single")
54
- btn_batch.click(fn=image_processing_batch, inputs=[background_image, links], outputs=[preview, output_zip], api_name="image_processing_batch")
55
 
56
  demo.launch()
 
1
  import gradio as gr
2
  from infra import image_processing_single, image_processing_batch
3
 
4
+ with gr.Blocks(theme='Zarkel/IBM_Carbon_Theme', title='Image Generator') as demo:
5
  gr.HTML("""
6
  <h1>Product Image Generator</h1>
7
  <p>1. 배경 이미지를 업로드해주세요.<p>
 
19
  label="예제 배경 이미지")
20
  with gr.Tab("Single Mode"):
21
  with gr.Column():
22
+ product_image_size = gr.Slider(512, 1024, value=800, label="제품 이미지 사이즈")
23
  link = gr.Textbox(label="Image URL")
24
  gr.Examples(
25
  examples=["https://url.kr/yx85be", "https://url.kr/if4wxo"],
 
31
  gr.HTML("<div>링크1(엔터) 링크2(엔터) ... 으로 구성된 .txt 파일을 업로드</div>")
32
  with gr.Column():
33
  links = gr.File(label="Image URLs (.txt file)", height=100)
34
+ product_image_size_batch = gr.Slider(512, 1024, value=800, label="제품 이미지 사이즈")
35
  gr.Examples(
36
  examples=[["examples/links.txt"]],
37
  inputs=links,
 
52
  output_zip = gr.File(label="Download Result Zip File")
53
 
54
  # evnets
55
+ btn_single.click(fn=image_processing_single, inputs=[background_image, link, product_image_size], outputs=[preview, output_zip], api_name="image_processing_single")
56
+ btn_batch.click(fn=image_processing_batch, inputs=[background_image, links, product_image_size_batch], outputs=[preview, output_zip], api_name="image_processing_batch")
57
 
58
  demo.launch()
infra.py CHANGED
@@ -78,84 +78,68 @@ def resize_image(image: Image.Image, max_size: int) -> Image.Image:
78
  return None
79
 
80
  def paste_to_background_type_a(background: Image.Image, product: Image.Image) -> Image.Image:
81
- # 배경에 제품 이미지 합성
82
  try:
83
- # 배경 이미지 크기 가져오기
84
  bg_width, bg_height = background.size
85
-
86
- # 제품 이미지 크기 가져오기
87
  product_width, product_height = product.size
88
-
89
- # 제품 이미지를 배경 이미지 중앙에 위치시키기
90
  offset = ((bg_width - product_width) // 2, (bg_height - product_height) // 2)
91
-
92
- # 알파 채널을 고려하여 합성
93
  background.paste(product, offset, mask=product)
94
  return background
95
-
96
  except Exception as e:
97
  print(f"Failed to paste product image to background: {e}")
98
  return None
99
-
100
  def paste_to_background_type_b(background: Image.Image, product: Image.Image, margin: int = 10) -> Image.Image:
101
  try:
102
- # 배경 이미지 크기 가져오기
103
  bg_width, bg_height = background.size
104
-
105
- # 제품 이미지 크기 가져오기
106
  product_width, product_height = product.size
107
-
108
- # 두 제품 이미지를 위한 전체 너비 계산 (제품 이미지 두 개 + 마진)
109
  total_width = (product_width * 2) + margin
110
-
111
- if total_width > bg_width:
112
- raise ValueError("Background is too narrow to fit two product images with the specified margin.")
113
-
114
- # 첫 번째 제품 이미지의 왼쪽 상단 좌표 계산
115
  left_offset = (bg_width - total_width) // 2
116
  top_offset = (bg_height - product_height) // 2
117
-
 
 
 
118
  # 두 번째 제품 이미지의 왼쪽 상단 좌표 계산
119
  right_offset = left_offset + product_width + margin
120
-
121
- # 번째 제품 이미지 배경에 합성
122
- background.paste(product, (left_offset, top_offset), mask=product)
123
-
124
- # 두 번째 제품 이미지 배경에 합성
125
  background.paste(product, (right_offset, top_offset), mask=product)
126
  return background
127
-
128
  except Exception as e:
129
  print(f"Failed to paste product images to background: {e}")
130
  return None
131
 
132
  def paste_to_background_type_c(background: Image.Image, product: Image.Image, margin: int = 10, top_margin: int = 15) -> Image.Image:
133
  try:
134
- # 배경 이미지 크기 가져오기
135
  bg_width, bg_height = background.size
136
-
137
- # 제품 이미지 크기 가져오기
138
  product_width, product_height = product.size
139
-
140
- # 먼저 type_b 형태로 아래 두 제품 이미지를 배치
141
  background_with_two_products = paste_to_background_type_b(background, product, margin)
142
 
143
- # 중앙 상단에 위치할 제품 이미지의 오프셋 계산
144
  center_offset_x = (bg_width - product_width) // 2
145
  center_offset_y = ((bg_height - product_height) // 2) + top_margin
146
-
147
- if center_offset_y < 0:
148
- raise ValueError("Background is too small to fit three product images with the specified top margin.")
149
-
150
- # 세 번째 제품 이미지 배경에 합성 (중앙 상단)
151
  background_with_two_products.paste(product, (center_offset_x, center_offset_y), mask=product)
152
-
153
- # 결과 이미지 저장 및 반환
154
  return background_with_two_products
155
-
156
  except Exception as e:
157
  print(f"Failed to paste product images to background: {e}")
158
  return None
 
159
 
160
  def create_zip_file(images: list) -> str:
161
  # 임시 파일 생성
@@ -174,11 +158,8 @@ def create_zip_file(images: list) -> str:
174
  temp_zip_path = temp_zip.name
175
 
176
  return temp_zip_path
177
-
178
- def image_processing_single(background_image: Image.Image, product_image_url: str):
179
- # 배경 이미지 크기 조정
180
- background_image = background_image.resize((BACKGROUND_IMAGE_MAX_SIZE, BACKGROUND_IMAGE_MAX_SIZE))
181
 
 
182
  # 이미지 다운로드
183
  original_image = download_image(product_image_url)
184
 
@@ -189,20 +170,31 @@ def image_processing_single(background_image: Image.Image, product_image_url: st
189
  cropped_image = crop_image(removebg_image)
190
 
191
  # 크롭된 이미지 원하는 사이즈로 resize
192
- resized_image = resize_image(cropped_image, PRODUCT_IMAGE_MAX_SIZE)
193
 
194
  # type_a 합성
195
  type_a_image = paste_to_background_type_a(background_image.copy(), resized_image)
196
  type_b_image = paste_to_background_type_b(background_image.copy(), resized_image, TYPD_B_MARGIN)
197
  type_c_image = paste_to_background_type_c(background_image.copy(), resized_image, TYPE_C_MARGIN_1, TYPE_C_MARGIN_2)
198
 
 
 
 
 
 
 
 
 
 
 
 
199
  # 결과 이미지 반환
200
  image_list = [type_a_image, type_b_image, type_c_image]
201
  zip_file_path = create_zip_file(image_list)
202
 
203
  return image_list, zip_file_path
204
 
205
- def image_processing_batch(background_image: Image.Image, product_image_url_file_path: str):
206
  # 배경 이미지 크기 조정
207
  background_image = background_image.resize((BACKGROUND_IMAGE_MAX_SIZE, BACKGROUND_IMAGE_MAX_SIZE))
208
 
@@ -221,22 +213,7 @@ def image_processing_batch(background_image: Image.Image, product_image_url_file
221
 
222
  preview_image_list, image_list = [], []
223
  for idx, product_image_url in enumerate(product_image_url_list):
224
- # 이미지 다운로드
225
- original_image = download_image(product_image_url)
226
-
227
- # 이미지 누끼따기
228
- removebg_image = remove_background(original_image)
229
-
230
- # 이미지 크롭
231
- cropped_image = crop_image(removebg_image)
232
-
233
- # 크롭된 이미지 원하는 사이즈로 resize
234
- resized_image = resize_image(cropped_image, PRODUCT_IMAGE_MAX_SIZE)
235
-
236
- # type_a 합성
237
- type_a_image = paste_to_background_type_a(background_image.copy(), resized_image)
238
- type_b_image = paste_to_background_type_b(background_image.copy(), resized_image, TYPD_B_MARGIN)
239
- type_c_image = paste_to_background_type_c(background_image.copy(), resized_image, TYPE_C_MARGIN_1, TYPE_C_MARGIN_2)
240
 
241
  image_list.append(type_a_image)
242
  image_list.append(type_b_image)
 
78
  return None
79
 
80
  def paste_to_background_type_a(background: Image.Image, product: Image.Image) -> Image.Image:
 
81
  try:
 
82
  bg_width, bg_height = background.size
 
 
83
  product_width, product_height = product.size
84
+
85
+ # 제품 이미지를 배경 이미지 중앙에 위치시키기 (음수 오프셋 허용)
86
  offset = ((bg_width - product_width) // 2, (bg_height - product_height) // 2)
87
+
88
+ # 알파 채널을 고려하여 합성 (음수 오프셋 지원)
89
  background.paste(product, offset, mask=product)
90
  return background
91
+
92
  except Exception as e:
93
  print(f"Failed to paste product image to background: {e}")
94
  return None
95
+
96
  def paste_to_background_type_b(background: Image.Image, product: Image.Image, margin: int = 10) -> Image.Image:
97
  try:
 
98
  bg_width, bg_height = background.size
 
 
99
  product_width, product_height = product.size
100
+
101
+ # 두 제품 이미지를 위한 전체 너비 계산 (음수 허용)
102
  total_width = (product_width * 2) + margin
103
+
104
+ # 번째 제품 이미지의 왼쪽 상단 좌표 계산 (음수 오프셋 허용)
 
 
 
105
  left_offset = (bg_width - total_width) // 2
106
  top_offset = (bg_height - product_height) // 2
107
+
108
+ # 첫 번째 제품 이미지 합성
109
+ background.paste(product, (left_offset, top_offset), mask=product)
110
+
111
  # 두 번째 제품 이미지의 왼쪽 상단 좌표 계산
112
  right_offset = left_offset + product_width + margin
113
+
114
+ # 번째 제품 이미지 합성
 
 
 
115
  background.paste(product, (right_offset, top_offset), mask=product)
116
  return background
117
+
118
  except Exception as e:
119
  print(f"Failed to paste product images to background: {e}")
120
  return None
121
 
122
  def paste_to_background_type_c(background: Image.Image, product: Image.Image, margin: int = 10, top_margin: int = 15) -> Image.Image:
123
  try:
 
124
  bg_width, bg_height = background.size
 
 
125
  product_width, product_height = product.size
126
+
127
+ # 아래 두 제품 이미지를 배치
128
  background_with_two_products = paste_to_background_type_b(background, product, margin)
129
 
130
+ # 중앙 상단에 위치할 제품 이미지의 오프셋 계산 (음수 오프셋 허용)
131
  center_offset_x = (bg_width - product_width) // 2
132
  center_offset_y = ((bg_height - product_height) // 2) + top_margin
133
+
134
+ # 번째 제품 이미지 합성 (중앙 상단)
 
 
 
135
  background_with_two_products.paste(product, (center_offset_x, center_offset_y), mask=product)
136
+
 
137
  return background_with_two_products
138
+
139
  except Exception as e:
140
  print(f"Failed to paste product images to background: {e}")
141
  return None
142
+
143
 
144
  def create_zip_file(images: list) -> str:
145
  # 임시 파일 생성
 
158
  temp_zip_path = temp_zip.name
159
 
160
  return temp_zip_path
 
 
 
 
161
 
162
+ def image_processing(background_image: Image.Image, product_image_url: str, product_image_size: int = 650):
163
  # 이미지 다운로드
164
  original_image = download_image(product_image_url)
165
 
 
170
  cropped_image = crop_image(removebg_image)
171
 
172
  # 크롭된 이미지 원하는 사이즈로 resize
173
+ resized_image = resize_image(cropped_image, product_image_size)
174
 
175
  # type_a 합성
176
  type_a_image = paste_to_background_type_a(background_image.copy(), resized_image)
177
  type_b_image = paste_to_background_type_b(background_image.copy(), resized_image, TYPD_B_MARGIN)
178
  type_c_image = paste_to_background_type_c(background_image.copy(), resized_image, TYPE_C_MARGIN_1, TYPE_C_MARGIN_2)
179
 
180
+ # 결과 이미지 반환
181
+ return type_a_image, type_b_image, type_c_image
182
+
183
+
184
+ def image_processing_single(background_image: Image.Image, product_image_url: str, product_image_size: int = 650):
185
+ # 배경 이미지 크기 조정
186
+ background_image = background_image.resize((BACKGROUND_IMAGE_MAX_SIZE, BACKGROUND_IMAGE_MAX_SIZE))
187
+
188
+ # 이미지 프로세싱
189
+ type_a_image, type_b_image, type_c_image = image_processing(background_image, product_image_url, product_image_size)
190
+
191
  # 결과 이미지 반환
192
  image_list = [type_a_image, type_b_image, type_c_image]
193
  zip_file_path = create_zip_file(image_list)
194
 
195
  return image_list, zip_file_path
196
 
197
+ def image_processing_batch(background_image: Image.Image, product_image_url_file_path: str, product_image_size: int = 650):
198
  # 배경 이미지 크기 조정
199
  background_image = background_image.resize((BACKGROUND_IMAGE_MAX_SIZE, BACKGROUND_IMAGE_MAX_SIZE))
200
 
 
213
 
214
  preview_image_list, image_list = [], []
215
  for idx, product_image_url in enumerate(product_image_url_list):
216
+ type_a_image, type_b_image, type_c_image = image_processing(background_image, product_image_url, product_image_size)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
 
218
  image_list.append(type_a_image)
219
  image_list.append(type_b_image)