Вы не можете выбрать более 25 тем
Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
130 строки
5.2 KiB
130 строки
5.2 KiB
import os
|
|
# import hashlib
|
|
from calculate.utils.files import Process, join_paths
|
|
from calculate.templates.format.base_format import FormatError
|
|
from typing import NoReturn, Union, List, Tuple, Optional
|
|
|
|
|
|
class ImageMagickError(FormatError):
|
|
pass
|
|
|
|
|
|
class ImageMagick:
|
|
def __init__(self, chroot: str = '/'):
|
|
self._chroot_path: str = chroot
|
|
self.init_commands(chroot)
|
|
self.default_opts: List[str] = []
|
|
|
|
@property
|
|
def available(self) -> bool:
|
|
return bool(self.convert_cmd and self.identify_cmd)
|
|
|
|
@property
|
|
def chrooted(self) -> bool:
|
|
return self._chroot_path != '/'
|
|
|
|
def init_commands(self, chroot: str) -> NoReturn:
|
|
self.convert_cmd: str = "/usr/bin/convert"
|
|
self.identify_cmd: str = "/usr/bin/identify"
|
|
self.chroot_cmd: str = "/bin/chroot"
|
|
self.bash_cmd: str = "/bin/bash"
|
|
|
|
if not os.path.exists(join_paths(chroot, self.convert_cmd)):
|
|
self.convert_cmd = None
|
|
if not os.path.exists(join_paths(chroot, self.identify_cmd)):
|
|
self.identify_cmd = None
|
|
|
|
def trim_prefix_path(self, filename: str) -> Union[str, None]:
|
|
retpath = "/{}".format(os.path.relpath(filename, self._chroot_path))
|
|
if retpath.startswith("/.."):
|
|
return None
|
|
return retpath
|
|
|
|
def get_image_resolution(self, source: str
|
|
) -> Union[None, Tuple[int, int]]:
|
|
'''Метод для получения разрешения указанного изображения,
|
|
с помощью команды 'identify -format %w %h <path_to_image>'.'''
|
|
if self.chrooted:
|
|
identify = Process(self.chroot_cmd, self._chroot_path,
|
|
self.bash_cmd, "-c",
|
|
" ".join([self.identify_cmd,
|
|
"-format '%w %h'", source]))
|
|
else:
|
|
identify = Process(self.identify_cmd, "-format", "%w %h", source)
|
|
|
|
if identify.success():
|
|
result = identify.read()
|
|
swidth, sheight = result.split(" ")
|
|
|
|
if swidth.isdigit() and sheight.isdigit():
|
|
return int(swidth), int(sheight)
|
|
else:
|
|
raise ImageMagickError(f"Can not parse: '{result}'")
|
|
else:
|
|
raise ImageMagickError(identify.read_error())
|
|
|
|
def convert(self, source: str, target: str, *opts: List[str],
|
|
image_format: Optional[str] = None) -> bool:
|
|
command = [self.convert_cmd, "-quality", "95",
|
|
source]
|
|
command.extend(self.default_opts)
|
|
command.extend(opts)
|
|
if image_format is not None:
|
|
command.append(f"{image_format}:{target}")
|
|
else:
|
|
command.append(target)
|
|
if self.chrooted:
|
|
convert = Process(self.chroot_cmd, self._chroot_path,
|
|
self.bash_cmd, "-c",
|
|
" ".join(command))
|
|
else:
|
|
convert = Process(*command)
|
|
if convert.success():
|
|
return True
|
|
else:
|
|
raise ImageMagickError(convert.read_error())
|
|
|
|
def convert_resize_crop_center(self, source: str, target: str,
|
|
height: int, width: int,
|
|
image_format: Optional[str] = None) -> bool:
|
|
# if ((width == self.source_width and height == self.source_height) and
|
|
# (source.rpartition('.')[2] == target.rpartition('.')[2])):
|
|
# with write_file(target) as sf:
|
|
# sf.write(read_file(source))
|
|
# return True
|
|
res = f"{width}x{height}"
|
|
return self.convert(source, target, "-quality", "95",
|
|
"-resize", f"{res}^",
|
|
"-strip", "-gravity", "center",
|
|
"-crop", f"{res}+0+0",
|
|
image_format=image_format)
|
|
|
|
def convert_resize_gfxboot(self, source: str, target: str,
|
|
height: int, width: int,
|
|
image_format: Optional[str] = None) -> bool:
|
|
res = f"{width}x{height}"
|
|
return self.convert(source, target, "-quality", "95",
|
|
"-resize", f"{res}^",
|
|
"-strip", "-gravity", "center",
|
|
"-crop", f"{res}+0+0",
|
|
"-sampling-factor", "2x2",
|
|
"-interlace", "none",
|
|
"-set", "units", "PixelsPerSecond",
|
|
image_format=image_format)
|
|
|
|
def get_image_format(self, source: str) -> str:
|
|
"""Метод для получения формата указанного файла."""
|
|
if self.chrooted:
|
|
identify = Process(self.chroot_cmd, self._chroot_path,
|
|
self.bash_cmd, "-c",
|
|
" ".join([self.identify_cmd,
|
|
"-format '%m'", source]))
|
|
else:
|
|
identify = Process(self.identify_cmd, "-format", "%m", source)
|
|
|
|
if identify.success():
|
|
image_format = identify.read()
|
|
return image_format
|
|
else:
|
|
raise ImageMagickError(f"{identify.read_error()}")
|