修改calman灰阶点击异常、修改色准结果显示异常
This commit is contained in:
@@ -293,62 +293,107 @@ def _call_pqtest_upload(file_path: str, timeout: float = API_UPLOAD_TIMEOUT, aut
|
||||
iw, ih = img.size
|
||||
except Exception as exc:
|
||||
raise ValueError(f"无法读取图片: {exc}") from exc
|
||||
|
||||
# 检查大小,如需则缩放
|
||||
|
||||
size = os.path.getsize(file_path)
|
||||
needs_resize = (iw > UPLOAD_MAX_PIXELS or ih > UPLOAD_MAX_PIXELS or size > UPLOAD_MAX_BYTES)
|
||||
|
||||
file_stem = os.path.splitext(os.path.basename(file_path))[0]
|
||||
upload_ext = ext
|
||||
mime = mimetypes.guess_type(file_path)[0] or "application/octet-stream"
|
||||
|
||||
if needs_resize:
|
||||
if not auto_resize:
|
||||
if iw > UPLOAD_MAX_PIXELS or ih > UPLOAD_MAX_PIXELS:
|
||||
raise ValueError(f"分辨率超过 4096×4096(当前 {iw}×{ih})")
|
||||
else:
|
||||
raise ValueError(f"图片超过 10MB 限制(当前 {size/1024/1024:.2f}MB)")
|
||||
|
||||
# 自动缩放:等比例缩放至 4096×4096 以内
|
||||
logger.info("[AIImage][UPLOAD] 自动缩放 %dx%d (%.1fMB) 至 ≤4096×4096",
|
||||
iw, ih, size/1024/1024)
|
||||
scale = min(UPLOAD_MAX_PIXELS / iw, UPLOAD_MAX_PIXELS / ih, 1.0)
|
||||
new_w, new_h = max(1, int(iw * scale)), max(1, int(ih * scale))
|
||||
|
||||
raise ValueError(f"图片超过 10MB 限制(当前 {size/1024/1024:.2f}MB)")
|
||||
|
||||
logger.info(
|
||||
"[AIImage][UPLOAD] 自动处理超限图片 %dx%d (%.2fMB)",
|
||||
iw,
|
||||
ih,
|
||||
size / 1024 / 1024,
|
||||
)
|
||||
|
||||
with Image.open(file_path) as img:
|
||||
img_resized = img.resize((new_w, new_h), Image.LANCZOS)
|
||||
# 重压至 10MB 以下
|
||||
# 首先尝试原格式
|
||||
tmp_io = BytesIO()
|
||||
fmt = "PNG" if ext == ".png" else "JPEG"
|
||||
save_kw = {"format": fmt}
|
||||
img_resized.save(tmp_io, **save_kw)
|
||||
tmp_bytes = tmp_io.getvalue()
|
||||
|
||||
if len(tmp_bytes) <= UPLOAD_MAX_BYTES:
|
||||
file_bytes = tmp_bytes
|
||||
working = img.copy()
|
||||
|
||||
# 先做一次分辨率约束,避免后续压缩开销过大。
|
||||
scale = min(UPLOAD_MAX_PIXELS / max(1, working.width), UPLOAD_MAX_PIXELS / max(1, working.height), 1.0)
|
||||
if scale < 1.0:
|
||||
working = working.resize(
|
||||
(max(1, int(working.width * scale)), max(1, int(working.height * scale))),
|
||||
Image.LANCZOS,
|
||||
)
|
||||
|
||||
best_bytes = b""
|
||||
best_mime = mime
|
||||
best_ext = upload_ext
|
||||
|
||||
# 第一优先:保持原格式。
|
||||
try:
|
||||
raw_io = BytesIO()
|
||||
if ext == ".png":
|
||||
working.save(raw_io, format="PNG", optimize=True)
|
||||
raw_mime, raw_ext = "image/png", ".png"
|
||||
else:
|
||||
# 原格式太大,转换为 JPEG 并压缩
|
||||
logger.info("[AIImage][UPLOAD] 原格式超过限制,转为 JPEG 并压缩")
|
||||
quality = 95
|
||||
while quality >= 50:
|
||||
tmp_io = BytesIO()
|
||||
img_resized.save(tmp_io, format="JPEG", quality=quality, optimize=True)
|
||||
tmp_bytes = tmp_io.getvalue()
|
||||
if len(tmp_bytes) <= UPLOAD_MAX_BYTES:
|
||||
file_bytes = tmp_bytes
|
||||
rgb = working.convert("RGB") if working.mode not in {"RGB", "L"} else working
|
||||
rgb.save(raw_io, format="JPEG", quality=95, optimize=True)
|
||||
raw_mime, raw_ext = "image/jpeg", ".jpg"
|
||||
best_bytes = raw_io.getvalue()
|
||||
best_mime = raw_mime
|
||||
best_ext = raw_ext
|
||||
except Exception as exc:
|
||||
logger.warning("[AIImage][UPLOAD] 原格式编码失败,准备转 JPEG: %s", exc)
|
||||
|
||||
# 仍超限时,转 JPEG + 渐进压缩;如仍超限则继续降分辨率。
|
||||
if len(best_bytes) > UPLOAD_MAX_BYTES:
|
||||
if best_ext != ".jpg":
|
||||
logger.info("[AIImage][UPLOAD] 原格式仍超限,切换 JPEG 压缩")
|
||||
working_jpg = working.convert("RGB") if working.mode != "RGB" else working
|
||||
while True:
|
||||
compressed = b""
|
||||
for q in (95, 90, 85, 80, 75, 70, 65, 60, 55, 50):
|
||||
tmp = BytesIO()
|
||||
working_jpg.save(tmp, format="JPEG", quality=q, optimize=True)
|
||||
data = tmp.getvalue()
|
||||
compressed = data
|
||||
if len(data) <= UPLOAD_MAX_BYTES:
|
||||
break
|
||||
quality -= 5
|
||||
else:
|
||||
# 即使 quality=50 还是太大,也用这个版本上传(后端会处理)
|
||||
file_bytes = tmp_bytes
|
||||
|
||||
logger.info("[AIImage][UPLOAD] 缩放完成 %dx%d (%.1fMB)",
|
||||
new_w, new_h, len(file_bytes)/1024/1024)
|
||||
iw, ih = new_w, new_h
|
||||
best_bytes = compressed
|
||||
best_mime = "image/jpeg"
|
||||
best_ext = ".jpg"
|
||||
if len(best_bytes) <= UPLOAD_MAX_BYTES:
|
||||
break
|
||||
|
||||
next_w = max(256, int(working_jpg.width * 0.9))
|
||||
next_h = max(256, int(working_jpg.height * 0.9))
|
||||
if next_w == working_jpg.width and next_h == working_jpg.height:
|
||||
break
|
||||
if next_w <= 256 or next_h <= 256:
|
||||
break
|
||||
working_jpg = working_jpg.resize((next_w, next_h), Image.LANCZOS)
|
||||
|
||||
if len(best_bytes) > UPLOAD_MAX_BYTES:
|
||||
raise ValueError(
|
||||
f"自动压缩后仍超过 10MB(当前 {len(best_bytes)/1024/1024:.2f}MB),请更换图片"
|
||||
)
|
||||
|
||||
file_bytes = best_bytes
|
||||
mime = best_mime
|
||||
upload_ext = best_ext
|
||||
iw, ih = working.width, working.height
|
||||
logger.info(
|
||||
"[AIImage][UPLOAD] 自动处理完成 %dx%d %.2fMB (%s)",
|
||||
iw,
|
||||
ih,
|
||||
len(file_bytes) / 1024 / 1024,
|
||||
mime,
|
||||
)
|
||||
else:
|
||||
with open(file_path, "rb") as f:
|
||||
file_bytes = f.read()
|
||||
|
||||
mime = mimetypes.guess_type(file_path)[0] or "application/octet-stream"
|
||||
filename = f"{file_stem}{upload_ext}"
|
||||
boundary = "----pqAuto" + uuid.uuid4().hex
|
||||
filename = os.path.basename(file_path)
|
||||
crlf = b"\r\n"
|
||||
body = b"".join([
|
||||
b"--", boundary.encode("ascii"), crlf,
|
||||
|
||||
Reference in New Issue
Block a user