You've already forked ImageCompressor
mirror of
https://github.com/Llloooggg/ImageCompressor.git
synced 2026-03-06 03:26:23 +03:00
Вырезано сжатие с Pillow
This commit is contained in:
@@ -186,43 +186,7 @@ def compress_with_external(
|
|||||||
return False, path
|
return False, path
|
||||||
|
|
||||||
|
|
||||||
def compress_with_pillow(path: Path) -> Tuple[bool, Path]:
|
def compress_image(path: Path):
|
||||||
original_size = path.stat().st_size
|
|
||||||
temp_path = path.with_name(path.stem + ".pillowtmp" + path.suffix)
|
|
||||||
|
|
||||||
try:
|
|
||||||
with Image.open(path) as img:
|
|
||||||
exif = img.info.get("exif")
|
|
||||||
img_format = img.format
|
|
||||||
quality = 85
|
|
||||||
while quality >= 50:
|
|
||||||
img.save(
|
|
||||||
temp_path,
|
|
||||||
format=img_format,
|
|
||||||
optimize=True,
|
|
||||||
quality=quality,
|
|
||||||
exif=exif,
|
|
||||||
)
|
|
||||||
if temp_path.stat().st_size <= TARGET_SIZE:
|
|
||||||
break
|
|
||||||
quality -= 5
|
|
||||||
|
|
||||||
if temp_path.exists():
|
|
||||||
if temp_path.stat().st_size < original_size:
|
|
||||||
temp_path.replace(path)
|
|
||||||
return True, path
|
|
||||||
logging.error(
|
|
||||||
f"Не удалось сжать (не уменьшилось): {path} ({original_size // 1024} KB)"
|
|
||||||
)
|
|
||||||
temp_path.unlink()
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"Ошибка при сжатии {path} Pillow: {e}")
|
|
||||||
if temp_path.exists():
|
|
||||||
temp_path.unlink()
|
|
||||||
return False, path
|
|
||||||
|
|
||||||
|
|
||||||
def compress_image(path: Path, use_fallback: bool = False):
|
|
||||||
global processed_count, skipped_count, skipped_size_count, error_count, total_saved_bytes, total_images_original_size, total_images_new_size, processed_hashes
|
global processed_count, skipped_count, skipped_size_count, error_count, total_saved_bytes, total_images_original_size, total_images_new_size, processed_hashes
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -271,9 +235,6 @@ def compress_image(path: Path, use_fallback: bool = False):
|
|||||||
ext = path.suffix.lower()
|
ext = path.suffix.lower()
|
||||||
result, final_path = compress_with_external(path, ext)
|
result, final_path = compress_with_external(path, ext)
|
||||||
|
|
||||||
if not result and use_fallback:
|
|
||||||
result, final_path = compress_with_pillow(path)
|
|
||||||
|
|
||||||
new_size = final_path.stat().st_size
|
new_size = final_path.stat().st_size
|
||||||
total_images_new_size += new_size
|
total_images_new_size += new_size
|
||||||
|
|
||||||
@@ -372,28 +333,20 @@ def main():
|
|||||||
required = ["cjpeg-static.exe", "cwebp.exe"]
|
required = ["cjpeg-static.exe", "cwebp.exe"]
|
||||||
missing = [t for t in required if not get_tool_path(t).exists()]
|
missing = [t for t in required if not get_tool_path(t).exists()]
|
||||||
|
|
||||||
use_fallback = False
|
|
||||||
if missing:
|
if missing:
|
||||||
print("Не найдены:", ", ".join(missing))
|
print("Не найдены:", ", ".join(missing))
|
||||||
choice = input("Использовать Pillow? [y/n]: ").strip().lower()
|
logging.error("Не найдены:", ", ".join(missing))
|
||||||
if choice != "y":
|
return
|
||||||
print("Работа прервана.")
|
|
||||||
return
|
|
||||||
use_fallback = True
|
|
||||||
|
|
||||||
total_original_size = get_folder_size(input_dir)
|
total_original_size = get_folder_size(input_dir)
|
||||||
|
|
||||||
files = prepare_and_copy_files(input_dir, output_dir)
|
files = prepare_and_copy_files(input_dir, output_dir)
|
||||||
total_files = len(files)
|
total_files = len(files)
|
||||||
print(f"Найдено {total_files} изображений.")
|
print(f"Найдено {total_files} изображений.")
|
||||||
logging.info(
|
logging.info(f"Начато. Найдено {total_files} изображений.")
|
||||||
f"Начато. Найдено {total_files} изображений. Fallback = {use_fallback}"
|
|
||||||
)
|
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
|
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
|
||||||
futures = [
|
futures = [executor.submit(compress_image, f) for f in files]
|
||||||
executor.submit(compress_image, f, use_fallback) for f in files
|
|
||||||
]
|
|
||||||
for i, _ in enumerate(as_completed(futures), 1):
|
for i, _ in enumerate(as_completed(futures), 1):
|
||||||
print(f"\rОбработка: {i}/{len(files)}", end="")
|
print(f"\rОбработка: {i}/{len(files)}", end="")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user