fix(io): Unicode-safe cv2 image IO + un-eat the [gpu] install hint (v0.6.6)

Two CLI/IO robustness bugs surfaced by issues #17 and #19.

#17 -- non-ASCII image paths (Chinese/Cyrillic/accented) failed on Windows:
cv2.imread/imwrite use the platform ANSI code-page API, so the decode came back
empty with a "can't open/read file" warning. New image_io.imread/imwrite route
through np.fromfile+cv2.imdecode / cv2.imencode+tofile (Unicode-safe, byte-
identical output, cv2.imread None-semantics preserved); all 8 cv2 read/write
call sites now go through it. Behavior-neutral on macOS/Linux (already accept
UTF-8 paths), so the fix is correct-by-construction for the Windows-only bug.

#19 (incidental) -- rich parsed the "[gpu]" in the GPU-extra install hint as a
style tag and dropped it, so the printed command was the un-installable
"pip install 'remove-ai-watermarks'". Escaped as \[gpu] at both call sites.

Tests: test_image_io.py (non-ASCII round-trip, alpha, missing/empty/garbage
semantics); test_cli.py::TestGpuHintMarkup (install hint keeps the extra).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
test-user
2026-05-27 11:52:48 -07:00
co-authored by Claude Opus 4.7
parent d847b39292
commit 7b47fa9f6a
12 changed files with 189 additions and 17 deletions
+9 -6
View File
@@ -85,7 +85,9 @@ def _read_bgr_and_alpha(path: Path) -> tuple[np.ndarray | None, np.ndarray | Non
"""
import cv2
image = cv2.imread(str(path), cv2.IMREAD_UNCHANGED)
from remove_ai_watermarks import image_io
image = image_io.imread(path, cv2.IMREAD_UNCHANGED)
if image is None:
return None, None
if image.ndim == 2:
@@ -109,11 +111,12 @@ def _write_bgr_with_alpha(
forced to 0 inside that bbox (expanded by ``pad`` px) so the watermark area
becomes fully transparent in the saved file.
"""
import cv2
import numpy as np
from remove_ai_watermarks import image_io
if alpha is None or path.suffix.lower() not in _ALPHA_FORMATS:
cv2.imwrite(str(path), bgr)
image_io.imwrite(path, bgr)
return
alpha_out = alpha
@@ -127,7 +130,7 @@ def _write_bgr_with_alpha(
alpha_out[y0:y1, x0:x1] = 0
bgra = np.dstack([bgr, alpha_out])
cv2.imwrite(str(path), bgra)
image_io.imwrite(path, bgra)
def _run_doubao_if_selected(
@@ -481,7 +484,7 @@ def cmd_invisible(
if not invisible_available():
console.print(
"[red]Error:[/] GPU dependencies not installed.\n"
" Install them with: [bold]pip install 'remove-ai-watermarks[gpu]'[/]"
" Install them with: [bold]pip install 'remove-ai-watermarks\\[gpu]'[/]"
)
raise SystemExit(1)
@@ -744,7 +747,7 @@ def cmd_all(
if not invisible_available():
console.print(
" [yellow]⚠[/] Skipped — GPU dependencies not installed.\n"
" Install them with: [bold]pip install 'remove-ai-watermarks[gpu]'[/]"
" Install them with: [bold]pip install 'remove-ai-watermarks\\[gpu]'[/]"
)
else:
from remove_ai_watermarks.invisible_engine import InvisibleEngine