fix(upload): 모바일 QR 업로드 이미지 처리 수정
- PIL 이미지 처리 추가 (product-images API와 동일) - 800x800 리사이즈 - 200x200 썸네일 생성 - RGBA->RGB 변환 - 1:1 중앙 크롭
This commit is contained in:
parent
90cb91d644
commit
3507d17dc5
@ -7682,21 +7682,62 @@ def api_upload_session_image(session_id):
|
|||||||
return jsonify({'success': False, 'error': '세션이 만료되었습니다'}), 404
|
return jsonify({'success': False, 'error': '세션이 만료되었습니다'}), 404
|
||||||
|
|
||||||
# 이미지 데이터 받기
|
# 이미지 데이터 받기
|
||||||
|
import base64
|
||||||
|
from PIL import Image
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
if 'image' not in request.files:
|
if 'image' not in request.files:
|
||||||
# base64로 받은 경우
|
# base64로 받은 경우
|
||||||
data = request.get_json() or {}
|
data = request.get_json() or {}
|
||||||
image_base64 = data.get('image_base64')
|
image_data_raw = data.get('image_base64')
|
||||||
if not image_base64:
|
if not image_data_raw:
|
||||||
return jsonify({'success': False, 'error': '이미지가 필요합니다'}), 400
|
return jsonify({'success': False, 'error': '이미지가 필요합니다'}), 400
|
||||||
else:
|
else:
|
||||||
# 파일로 받은 경우
|
# 파일로 받은 경우
|
||||||
import base64
|
|
||||||
file = request.files['image']
|
file = request.files['image']
|
||||||
image_data = file.read()
|
image_data_raw = base64.b64encode(file.read()).decode('utf-8')
|
||||||
image_base64 = base64.b64encode(image_data).decode('utf-8')
|
|
||||||
|
|
||||||
# product_images.db에 저장
|
|
||||||
barcode = session['barcode']
|
barcode = session['barcode']
|
||||||
|
product_name = session.get('product_name', barcode)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# base64 디코딩 & PIL 이미지 처리
|
||||||
|
image_bytes = base64.b64decode(image_data_raw)
|
||||||
|
img = Image.open(BytesIO(image_bytes))
|
||||||
|
|
||||||
|
# RGBA -> RGB 변환
|
||||||
|
if img.mode == 'RGBA':
|
||||||
|
bg = Image.new('RGB', img.size, (255, 255, 255))
|
||||||
|
bg.paste(img, mask=img.split()[3])
|
||||||
|
img = bg
|
||||||
|
elif img.mode != 'RGB':
|
||||||
|
img = img.convert('RGB')
|
||||||
|
|
||||||
|
# 1:1 중앙 크롭
|
||||||
|
width, height = img.size
|
||||||
|
min_dim = min(width, height)
|
||||||
|
left = (width - min_dim) // 2
|
||||||
|
top = (height - min_dim) // 2
|
||||||
|
img = img.crop((left, top, left + min_dim, top + min_dim))
|
||||||
|
|
||||||
|
# 800x800 리사이즈
|
||||||
|
img = img.resize((800, 800), Image.LANCZOS)
|
||||||
|
|
||||||
|
# base64 변환 (원본)
|
||||||
|
buffer = BytesIO()
|
||||||
|
img.save(buffer, format='JPEG', quality=90)
|
||||||
|
image_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
|
||||||
|
|
||||||
|
# 썸네일 생성 (200x200)
|
||||||
|
thumb_img = img.resize((200, 200), Image.LANCZOS)
|
||||||
|
thumb_buffer = BytesIO()
|
||||||
|
thumb_img.save(thumb_buffer, format='JPEG', quality=85)
|
||||||
|
thumbnail_base64 = base64.b64encode(thumb_buffer.getvalue()).decode('utf-8')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'success': False, 'error': f'이미지 처리 실패: {str(e)}'}), 400
|
||||||
|
|
||||||
|
# SQLite 저장
|
||||||
try:
|
try:
|
||||||
img_db_path = Path(__file__).parent / 'db' / 'product_images.db'
|
img_db_path = Path(__file__).parent / 'db' / 'product_images.db'
|
||||||
conn = sqlite3.connect(str(img_db_path))
|
conn = sqlite3.connect(str(img_db_path))
|
||||||
@ -7706,26 +7747,24 @@ def api_upload_session_image(session_id):
|
|||||||
cursor.execute('SELECT id FROM product_images WHERE barcode = ?', (barcode,))
|
cursor.execute('SELECT id FROM product_images WHERE barcode = ?', (barcode,))
|
||||||
existing = cursor.fetchone()
|
existing = cursor.fetchone()
|
||||||
|
|
||||||
product_name = session.get('product_name', barcode) # 세션에서 가져오거나 바코드 사용
|
|
||||||
|
|
||||||
if existing:
|
if existing:
|
||||||
cursor.execute('''
|
cursor.execute('''
|
||||||
UPDATE product_images
|
UPDATE product_images
|
||||||
SET image_base64 = ?, updated_at = CURRENT_TIMESTAMP
|
SET image_base64 = ?, thumbnail_base64 = ?, status = 'manual', updated_at = datetime('now')
|
||||||
WHERE barcode = ?
|
WHERE barcode = ?
|
||||||
''', (image_base64, barcode))
|
''', (image_base64, thumbnail_base64, barcode))
|
||||||
else:
|
else:
|
||||||
cursor.execute('''
|
cursor.execute('''
|
||||||
INSERT INTO product_images (barcode, product_name, image_base64, status, created_at)
|
INSERT INTO product_images (barcode, product_name, image_base64, thumbnail_base64, status)
|
||||||
VALUES (?, ?, ?, 'manual', CURRENT_TIMESTAMP)
|
VALUES (?, ?, ?, ?, 'manual')
|
||||||
''', (barcode, product_name, image_base64))
|
''', (barcode, product_name, image_base64, thumbnail_base64))
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
# 세션 상태 업데이트
|
# 세션 상태 업데이트
|
||||||
session['status'] = 'uploaded'
|
session['status'] = 'uploaded'
|
||||||
session['image_base64'] = image_base64
|
session['image_base64'] = thumbnail_base64 # 폴링용으로 썸네일 사용
|
||||||
|
|
||||||
return jsonify({'success': True, 'message': '이미지가 저장되었습니다'})
|
return jsonify({'success': True, 'message': '이미지가 저장되었습니다'})
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user