mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-20 21:57:14 +08:00
feat: optimize vision image compression
This commit is contained in:
@@ -167,7 +167,7 @@ class Vision(BaseTool):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _maybe_compress(path: str) -> str:
|
def _maybe_compress(path: str) -> str:
|
||||||
"""Compress image if larger than threshold; return path to use."""
|
"""Compress image to under COMPRESS_THRESHOLD with max long-edge 1536px."""
|
||||||
file_size = os.path.getsize(path)
|
file_size = os.path.getsize(path)
|
||||||
if file_size <= COMPRESS_THRESHOLD:
|
if file_size <= COMPRESS_THRESHOLD:
|
||||||
return path
|
return path
|
||||||
@@ -175,27 +175,47 @@ class Vision(BaseTool):
|
|||||||
tmp = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False)
|
tmp = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False)
|
||||||
tmp.close()
|
tmp.close()
|
||||||
|
|
||||||
try:
|
def _try_sips(max_dim: str, quality: str) -> bool:
|
||||||
# macOS: use sips
|
try:
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["sips", "-Z", "800", path, "--out", tmp.name],
|
["sips", "-Z", max_dim, "-s", "formatOptions", quality,
|
||||||
capture_output=True, check=True,
|
path, "--out", tmp.name],
|
||||||
)
|
capture_output=True, check=True,
|
||||||
logger.debug(f"[Vision] Compressed image ({file_size // 1024}KB -> {os.path.getsize(tmp.name) // 1024}KB)")
|
)
|
||||||
return tmp.name
|
return True
|
||||||
except (FileNotFoundError, subprocess.CalledProcessError):
|
except (FileNotFoundError, subprocess.CalledProcessError):
|
||||||
pass
|
return False
|
||||||
|
|
||||||
try:
|
def _try_convert(max_dim: str, quality: str) -> bool:
|
||||||
# Linux: use ImageMagick convert
|
try:
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["convert", path, "-resize", "800x800>", tmp.name],
|
["convert", path, "-resize", f"{max_dim}x{max_dim}>",
|
||||||
capture_output=True, check=True,
|
"-quality", quality, tmp.name],
|
||||||
)
|
capture_output=True, check=True,
|
||||||
logger.debug(f"[Vision] Compressed image ({file_size // 1024}KB -> {os.path.getsize(tmp.name) // 1024}KB)")
|
)
|
||||||
|
return True
|
||||||
|
except (FileNotFoundError, subprocess.CalledProcessError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
attempts = [
|
||||||
|
("1536", "85"),
|
||||||
|
("1536", "70"),
|
||||||
|
("1536", "50"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for max_dim, quality in attempts:
|
||||||
|
ok = _try_sips(max_dim, quality) or _try_convert(max_dim, quality)
|
||||||
|
if not ok:
|
||||||
|
continue
|
||||||
|
new_size = os.path.getsize(tmp.name)
|
||||||
|
logger.debug(f"[Vision] Compressed image "
|
||||||
|
f"({file_size // 1024}KB -> {new_size // 1024}KB, "
|
||||||
|
f"max_dim={max_dim}, q={quality})")
|
||||||
|
if new_size <= COMPRESS_THRESHOLD:
|
||||||
|
return tmp.name
|
||||||
|
|
||||||
|
if os.path.exists(tmp.name) and os.path.getsize(tmp.name) > 0:
|
||||||
return tmp.name
|
return tmp.name
|
||||||
except (FileNotFoundError, subprocess.CalledProcessError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
os.remove(tmp.name)
|
os.remove(tmp.name)
|
||||||
return path
|
return path
|
||||||
|
|||||||
Reference in New Issue
Block a user