Example #1
0
    def test_registered_extensions_uninitialized(self):
        # Arrange
        Image._initialized = 0
        extension = Image.EXTENSION
        Image.EXTENSION = {}

        # Act
        Image.registered_extensions()

        # Assert
        self.assertEqual(Image._initialized, 2)

        # Restore the original state and assert
        Image.EXTENSION = extension
        self.assertTrue(Image.EXTENSION)
Example #2
0
 def get_name(self, name, format):
     extensions = Image.registered_extensions()
     extensions = {v: k for k, v in extensions.items()}
     extensions.update(DEFAULT_FORMAT_EXTENSIONS)
     if format in extensions:
         name = name.rsplit('.', 1)[0] + extensions[format]
     return name
Example #3
0
 def get_name(self, name, format):
     extensions = Image.registered_extensions()
     extensions = {v: k for k, v in extensions.items()}
     extensions.update({
         "PNG": ".png",  # It uses .apng otherwise
     })
     extensions.update(DEFAULT_FORMAT_EXTENSIONS)
     if format in extensions:
         name = name.rsplit('.', 1)[0] + extensions[format]
     return name
Example #4
0
    def get_file_entry(self):
        local_file = None
        # don't provide file in case this event is out of the history window
        last_count = self._get_metric_count(self.metric, self.variant, next=False)
        if abs(self._count - last_count) > self._file_history_size:
            output = None
        elif isinstance(self._image_data, (six.StringIO, six.BytesIO)):
            output = self._image_data
        elif self._image_data is not None:
            image_data = self._image_data
            if not isinstance(image_data, np.ndarray):
                # try conversion, if it fails we'll leave it to the user.
                image_data = np.ndarray(image_data, dtype=np.uint8)
            image_data = np.atleast_3d(image_data)
            if image_data.dtype != np.uint8:
                if np.issubdtype(image_data.dtype, np.floating) and image_data.max() <= 1.0:
                    image_data = (image_data * 255).astype(np.uint8)
                else:
                    image_data = image_data.astype(np.uint8)
            shape = image_data.shape
            height, width, channel = shape[:3]
            if channel == 1:
                image_data = np.reshape(image_data, (height, width))

            # serialize image
            image = Image.fromarray(image_data)
            output = six.BytesIO()
            image_format = Image.registered_extensions().get(self._format.lower(), 'JPEG')
            image.save(output, format=image_format, quality=self._quality)
            output.seek(0)
        else:
            # noinspection PyBroadException
            try:
                output = pathlib2.Path(self._local_image_path)
                if not output.is_file():
                    output = None
            except Exception:
                output = None

            if output is None:
                from ...debugging.log import LoggerRoot
                LoggerRoot.get_base_logger().warning(
                    'Skipping upload, could not find object file \'{}\''.format(self._local_image_path))
                return None

        return self.FileEntry(
            event=self,
            name=self._upload_filename,
            stream=output,
            url_prop='url',
            key_prop='key',
            upload_uri=self._upload_uri,
            delete_local_file=local_file if self._delete_after_upload else None,
            retries=self.retries,
        )
Example #5
0
 def append_image(self):
     extensions = tuple(Image.registered_extensions().keys())
     images = tkFileDialog.askopenfilename(filetypes=[('Image File', extensions)], multiple=True)
     if len(images) == 0:
         return
     #
     for i in images:
         if i in self._image_list:
             continue
         self._image_list.append(i)
     self._filenames.set(' '.join(os.path.basename(i) for i in self._image_list))
def show_supported_formats():
    def rebuild_dic(formats, exts):
        return {
            f: [ext for ext, fmt in exts.items() if f == fmt]
            for f in formats
        }

    exts = Image.registered_extensions()
    formats = sorted(list(set(exts.values())))

    for f, exts in rebuild_dic(formats, exts).items():
        print('{} ({})'.format(f, ', '.join(exts)))
Example #7
0
    def test_registered_extensions(self):
        # Arrange
        # Open an image to trigger plugin registration
        Image.open('Tests/images/rgb.jpg')

        # Act
        extensions = Image.registered_extensions()

        # Assert
        self.assertTrue(extensions)
        for ext in ['.cur', '.icns', '.tif', '.tiff']:
            self.assertIn(ext, extensions)
Example #8
0
    def test_registered_extensions(self):
        # Arrange
        # Open an image to trigger plugin registration
        Image.open("Tests/images/rgb.jpg")

        # Act
        extensions = Image.registered_extensions()

        # Assert
        self.assertTrue(extensions)
        for ext in [".cur", ".icns", ".tif", ".tiff"]:
            self.assertIn(ext, extensions)
Example #9
0
    def test_registered_extensions(self):
        # Arrange
        # Open an image to trigger plugin registration
        Image.open('Tests/images/rgb.jpg')

        # Act
        extensions = Image.registered_extensions()

        # Assert
        self.assertTrue(extensions)
        for ext in ['.cur', '.icns', '.tif', '.tiff']:
            self.assertIn(ext, extensions)
Example #10
0
def write_image(file_path, image):
    file, extension = path.splitext(file_path)
    if extension.lower() == ".webp":
        logging.error("writing .webp %s", os.path.abspath(file_path))
        fp = BytesIO()
        im_pil = Image.fromarray(image)
        im_pil.save(fp, Image.registered_extensions()['.webp'])

        storage.save(file_path, ContentFile(fp.getbuffer()))
    else:
        logging.info("writing jpeg %s %s", file_path, extension)
        encoded, image = cv2.imencode(extension, image)
        storage.save(file_path, ContentFile(image))
Example #11
0
    def test_registered_extensions(self):
        # Arrange
        # Open an image to trigger plugin registration
        with Image.open("Tests/images/rgb.jpg"):
            pass

        # Act
        extensions = Image.registered_extensions()

        # Assert
        assert extensions
        for ext in [".cur", ".icns", ".tif", ".tiff"]:
            assert ext in extensions
Example #12
0
def write_image(file_path, image):
    file, extension = path.splitext(file_path)
    if extension.lower() == ".webp":
        logging.info("writing .webp %s", file_path)
        fp = BytesIO()
        im_pil = Image.fromarray(image)
        im_pil.save(fp, Image.registered_extensions()['.webp'])

        storage.save(file_path, ContentFile(fp.getbuffer()))
    else:
        logging.info("writing jpeg %s %s", file_path, extension)
        encoded, image = cv2.imencode(extension, image)
        storage.save(file_path, ContentFile(image))
Example #13
0
 def __post_init__(self):
     if self.path.endswith("/"):
         raise ValueError("path cannot end with /")
     path, suffix = splitext(self.path)
     parts: List[str] = list(filter(None, path.split("/")))
     self.format = Image.registered_extensions().get(suffix)
     if self.format is None:
         raise ValueError("Unknown format")
     if len(parts) < 2:
         raise ValueError("Too few arguments")
     self.transform = parts[0]
     key_parts = parts[1:]
     self.key = "/".join(key_parts)
     self.key_path = f"/{self.key}"
     self.suffix = suffix
     self.name = key_parts.pop()
     self.folder = f"/{'/'.join(key_parts)}"
Example #14
0
def load_single_images_uncropped(dir_path, randomized=True):
    while True:
        listing = list(os.scandir(dir_path))
        if randomized:
            random.shuffle(list(listing))
        for entry in listing:
            if not os.path.splitext(entry.name)[1].lower(
            ) in Image.registered_extensions().keys():
                continue
            try:
                img = Image.open(entry.path)
            except OSError:
                # Ignore corrupt images.
                continue
            img = img.convert('RGB')
            tensor = np.array(img)
            yield tensor
Example #15
0
def save_image(lt_image, page_number, images_folder, pypdf_obj=None):
    """Try to save the image data from this LTImage object, and return the file name, if successful"""
    result = None
    if lt_image.stream:
        file_stream = lt_image.stream.get_rawdata()
        if file_stream:
            file_ext = determine_image_type(file_stream[0:4])
            if file_ext:
                file_name = ''.join(
                    [str(page_number), '_', lt_image.name, file_ext])
                if write_file(images_folder,
                              file_name,
                              file_stream,
                              flags='wb'):
                    result = file_name
            elif pypdf_obj:
                # try:
                # print(pypdf_obj)
                pypdf_obj = pypdf_obj["/" + lt_image.name]
                # print(pypdf_obj)

                size = (pypdf_obj['/Width'], pypdf_obj['/Height'])
                data = pypdf_obj.getData()
                if ('/ColorSpace' in pypdf_obj
                    ) and pypdf_obj['/ColorSpace'] == '/DeviceRGB':
                    mode = "RGB"
                else:
                    mode = "P"
                img = Image.frombytes(mode, size, data)
                file_name = ''.join(
                    [str(page_number), '_', lt_image.name, '.png'])
                form = Image.registered_extensions()['.png']
                fp = io.BytesIO()
                img.save(fp, form)
                if write_file(images_folder,
                              file_name,
                              fp.getvalue(),
                              flags='wb'):
                    result = file_name

                # except Exception as e:
                # 	print("Exception")
                # 	print(e)
                # 	return None
    return result
Example #16
0
def thumbnail(file,
              format,
              width=0,
              height=0,
              force="resize",
              resample=Image.ANTIALIAS,
              **kwargs):
    # quality=95
    width = int(width)
    height = int(height)
    # 判断是否需要处理图片
    if (width <= 0 or height <= 0) and force == "resize" and len(kwargs) == 0:
        return file
    img = Image.open(file)
    ori_width, ori_height = img.size
    if width <= 0 or height <= 0:
        width = ori_width
        height = ori_height

    if force in ("crop_center", "1"):
        # 中心裁剪:center_crop;
        left = (ori_width - width) / 2
        top = (ori_height - height) / 2
        right = (ori_width + width) / 2
        bottom = (ori_height + height) / 2
        new_img = img.crop((left, top, right, bottom))
    else:
        # resize;
        new_img = img.resize((width, height), int(resample))

    byte_io = io.BytesIO()
    save_format = Image.registered_extensions()[format.lower()]
    new_img.save(byte_io, format=save_format, **kwargs)
    byte_io.seek(0)
    # params_size = ("width", "height", "force")
    # extra_args = {"size": size, "thumbnail_size": thumbnail_size}
    return byte_io
Example #17
0
    def get_file_entry(self):
        self._generate_file_name()

        local_file = None

        # Notice that in case we are running with reporter in subprocess,
        # when we are here, the cls._metric_counters is actually empty,
        # since it was updated on the main process and this function is running from the subprocess.
        #
        # In the future, if we want to support multi processes reporting images with the same title/series,
        # we should move the _count & _filename selection into the subprocess, not the main process.
        # For the time being, this will remain a limitation of the Image reporting mechanism.

        if isinstance(self._image_data, (six.StringIO, six.BytesIO)):
            output = self._image_data
        elif self._image_data is not None:
            image_data = self._image_data
            if not isinstance(image_data, np.ndarray):
                # try conversion, if it fails we'll leave it to the user.
                image_data = np.ndarray(image_data, dtype=np.uint8)
            image_data = np.atleast_3d(image_data)
            if image_data.dtype != np.uint8:
                if np.issubdtype(image_data.dtype, np.floating) and image_data.max() <= 1.0:
                    image_data = (image_data * 255).astype(np.uint8)
                else:
                    image_data = image_data.astype(np.uint8)
            shape = image_data.shape
            height, width, channel = shape[:3]
            if channel == 1:
                image_data = np.reshape(image_data, (height, width))

            # serialize image
            image = Image.fromarray(image_data)
            output = six.BytesIO()
            image_format = Image.registered_extensions().get(str(self._format).lower(), 'JPEG')
            image.save(output, format=image_format, quality=int(self._quality))
            output.seek(0)
        else:
            # noinspection PyBroadException
            try:
                output = pathlib2.Path(self._local_image_path)
                if output.is_file():
                    local_file = output
                else:
                    output = None
            except Exception:
                output = None

            if output is None:
                from ...debugging.log import LoggerRoot
                LoggerRoot.get_base_logger().warning(
                    'Skipping upload, could not find object file \'{}\''.format(self._local_image_path))
                return None

        return self.FileEntry(
            event=self,
            name=self._upload_filename,
            stream=output,
            url_prop='url',
            key_prop='key',
            upload_uri=self._upload_uri,
            delete_local_file=local_file if self._delete_after_upload else None,
            retries=self.retries,
        )
Example #18
0
def load_file(fp, filetype=None, project=None):
    """
    Load the file and return an appropriate object containing the data.

    Args:
        fp (str / file): path to the file or file object to be displayed.
        filetype (str/None): File extension, if given this overwrites the assumption based on the filename.
        project (pyiron-Project/None): Project calling this function, provided to all objects referring to such.

        Supported file types are:
        '.h5', '.hdf'
        '.json'
        '.txt'
        '.csv'
        '.ipynb'
        Image extensions supported by PIL

    Returns:
        :class:`FileHDFio`: pointing to the file of filetype = '.h5'
        dict: containing data from file of filetype = '.json'
        list: of all lines from file for filetype = '.txt'
        :class:`pandas.DataFrame`: containing data from file of filetype = '.csv'

    """

    def _load_txt(file):
        if isinstance(file, str):
            with open(file, encoding="utf8") as f:
                return f.readlines()
        else:
            return file.readlines()

    def _load_ipynb(file):
        return OwnNotebookNode(nbformat.read(file, as_version=4))

    def _load_json(file):
        if isinstance(file, str):
            with open(file) as f:
                return json.load(f)
        else:
            return json.load(file)

    def _load_csv(file):
        return pandas.read_csv(file)

    def _load_img(file):
        return Image.open(file)

    def _load_default(file):
        try:
            return _load_txt(file)
        except Exception as e:
            raise IOError("File could not be loaded.") from e

    def _resolve_filetype(file, _filetype):
        if _filetype is None and isinstance(file, str):
            _, _filetype = os.path.splitext(file)
        elif _filetype is None and hasattr(file, "name"):
            _, _filetype = os.path.splitext(file.name)
        elif _filetype is None:
            return None
        elif _filetype[0] != ".":
            _filetype = "." + _filetype
        return _filetype.lower()

    filetype = _resolve_filetype(fp, filetype)

    if filetype in [".h5", ".hdf"] and isinstance(fp, str):
        if project is None:
            return FileHDFio(file_name=fp)
        else:
            return ProjectHDFio(file_name=fp, project=project)
    elif filetype in [".json"]:
        return _load_json(fp)
    elif filetype in [".txt"]:
        return _load_txt(fp)
    elif filetype in [".csv"]:
        return _load_csv(fp)
    elif _has_imported["nbformat"] and filetype in [".ipynb"]:
        return _load_ipynb(fp)
    elif _has_imported["PIL"] and filetype in Image.registered_extensions():
        return _load_img(fp)
    else:
        return _load_default(fp)
Example #19
0
    "Computational Materials Design (CM) Department"
)
__version__ = "0.1"
__maintainer__ = "Niklas Siemer"
__email__ = "*****@*****.**"
__status__ = "development"
__date__ = "Feb 02, 2021"


_has_imported = {}
try:
    from PIL import Image

    _has_imported["PIL"] = True
    # For some reason I do not know this forces PIL to always be aware of all possible Image extensions.
    Image.registered_extensions()
except ImportError:
    _has_imported["PIL"] = False
try:
    import nbformat, nbconvert

    _has_imported["nbformat"] = True
except ImportError:
    _has_imported["nbformat"] = False

if all(_has_imported.values()):
    import_alarm = ImportAlarm()
else:
    import_alarm = ImportAlarm(
        "Reduced functionality, since "
        + str(
Example #20
0
    def get(self):
        parse = reqparse.RequestParser()
        parse.add_argument('id', type=int, help='错误的id', default='0')
        parse.add_argument('width', type=int, help='wrong width', default=300)
        parse.add_argument('height',
                           type=int,
                           help='wrong height',
                           default=300)
        parse.add_argument('token', type=str, help='wrong token')
        args = parse.parse_args()
        # 获取当前文件夹id
        file_id = args.get('id')
        width = args.get('width')
        height = args.get('height')
        token = args.get('token')
        try:
            user = verify_token(token)
        except:
            response = make_response(jsonify(code=38, message='wrong token'))
            return response
        try:
            file_node = FileNode.query.get(file_id)
        except:
            response = make_response(
                jsonify(code=11, message='node not exist, query fail'))
            return response
        if file_node.user_id != user.uid:
            response = make_response(jsonify(code=38, message='wrong token'))
            return response
        if file_node == None:
            response = make_response(
                jsonify(code=11, message='node not exist, query fail'))
            return response
        if file_node.type_of_node in config['IMG_TYPE']:
            parent_id = file_node.parent_id
            filename = file_node.filename
            node_type = file_node.type_of_node
            # 生成文件名的 hash
            actual_filename = generate_file_name(parent_id, filename)
            # 结合 UPLOAD_FOLDER 得到最终文件的存储路径
            target_file = os.path.join(os.path.expanduser(UPLOAD_FOLDER),
                                       actual_filename)
            if os.path.exists(target_file):
                try:
                    with Image.open(target_file, mode='r') as img_data:
                        # img_data = Image.open(target_file)
                        img_data.thumbnail((width, height))

                        fp = io.BytesIO()
                        format = Image.registered_extensions()['.' + node_type]
                        img_data.save(fp, format)

                        response = make_response(fp.getvalue())
                        response.headers['Content-Type'] = 'image/' + node_type
                        return response
                except:
                    response = make_response(
                        jsonify(code=24, message='preview not allowed'))
                    return response
            else:
                response = make_response(
                    jsonify(code=22, message='file not exist'))
                return response
        else:
            response = make_response(
                jsonify(code=24, message='preview not allowed'))
            return response
Example #21
0
from glob import glob
from PIL import Image, ImageDraw
import os

allowed_extensions = Image.registered_extensions().keys()


def get_filenames_from_dir(dirpath, sort=True):
    dirpath = os.path.join(os.path.abspath(dirpath), '')
    image_names = []
    for ext in allowed_extensions:
        image_names += glob(dirpath + '*' + ext)
    if sort:
        image_names.sort()
    return image_names


def draw_rectangle(image, coords, stroke, color):
    draw = ImageDraw.Draw(image)

    draw.rectangle(
        coords,
        outline=color,
        width=stroke
    )
Example #22
0
 def get_name(self, name, format):
     extensions = Image.registered_extensions()
     extensions = {v: k for k, v in extensions.items()}
     if format in extensions:
         name = name.rsplit('.', 1)[0] + extensions[format]
     return name
Example #23
0
def to_mimetype(extension):
    save_format = Image.registered_extensions()[extension.lower()]
    return "image/{}".format(save_format.lower())
Example #24
0
    default=512,
)
parser.add_argument(
    "--config_file",
    help="Path and filename for a config file",
    default=os.path.splitext(sys.argv[0])[0] + '.cfg',
)
parser.add_argument(
    "--loglevel",
    help="Level of verbosity",
    default=logging.DEBUG,
)
parser.add_argument(
    "--source_extensions",
    help="Image file extensions separated by comma",
    default=','.join([i[1:] for i in Image.registered_extensions().keys()], ))
parser.add_argument(
    "--target_extension",
    help="target file extension",
    default='.png',
)
args = parser.parse_args()
args = dict(args._get_kwargs())
args = configuration_override(args['config_file'],
                              args,
                              keys=args.keys(),
                              one_time=False)

if not args['target_extension'].startswith('.'):
    args['target_extension'] = '.' + args['target_extension']
source_extensions = []
Example #25
0
def img_to_bytes(file, ext):
    fp = io.BytesIO()
    format = Image.registered_extensions()[ext]
    file.save(fp, format)
    return fp.getvalue()
Example #26
0
import logging
import os
import re
from copy import deepcopy

import numpy as np
from PIL import Image as Pil

try:
    import numexpr as ne
except ImportError:
    ne = None

logger = logging.getLogger(__name__)

PIL_IMAGE_FORMATS = Pil.registered_extensions()


def _pprint_pil_formats():
    res = ''
    row = []
    for i in PIL_IMAGE_FORMATS:
        if len(row) > 12:
            res = res + ", ".join(row) + ",\n"
            row = []
        row.append(i)
    return res + ", ".join(row)


PIL_IMAGE_FORMATS_STR = _pprint_pil_formats()
Example #27
0
def load_file(filename, filetype=None, project=None):
    """
        Load the file and return an appropriate object containing the data.

        Args:
            filename (str): path to the file to be displayed.
            filetype (str/None): File extension, if given this overwrites the assumption based on the filename.
            project (pyiron-Project/None): Project calling this function, provided to all objects referring to such.

            Supported file types are:
            '.h5', '.hdf'
            '.json'
            '.txt'
            '.csv'
            '.ipynb'
            Image extensions supported by PIL

        Returns:
            :class:`FileHDFio`: pointing to the file of filetype = '.h5'
            dict: containing data from file of filetype = '.json'
            list: of all lines from file for filetype = '.txt'
            :class:`pandas.DataFrame`: containing data from file of filetype = '.csv'

    """
    def _load_txt(file):
        with open(file, encoding='utf8') as f:
            return f.readlines()

    def _load_ipynb(file):
        return OwnNotebookNode(nbformat.read(file, as_version=4))

    def _load_json(file):
        with open(file) as f:
            return json.load(f)

    def _load_csv(file):
        return pandas.read_csv(file)

    def _load_img(file):
        return Image.open(file)

    def _load_default(file):
        try:
            return _load_txt(file)
        except Exception as e:
            raise IOError("File could not be loaded.") from e

    if filetype is None:
        _, filetype = os.path.splitext(filename)
    elif filetype[0] != '.':
        filetype = '.' + filetype
    filetype = filetype.lower()

    if filetype in ['.h5', '.hdf']:
        if project is None:
            return FileHDFio(file_name=filename)
        else:
            return ProjectHDFio(file_name=filename, project=project)
    elif filetype in ['.json']:
        return _load_json(filename)
    elif filetype in ['.txt']:
        return _load_txt(filename)
    elif filetype in ['.csv']:
        return _load_csv(filename)
    elif _has_imported['nbformat'] and filetype in ['.ipynb']:
        return _load_ipynb(filename)
    elif _has_imported['PIL'] and filetype in Image.registered_extensions():
        return _load_img(filename)
    else:
        return _load_default(filename)
Example #28
0
class ImageRequestProcessor:
    """
        Aim to get response and parse the error content
    """
    SCREEN_WIDTH = os.get_terminal_size(0)[0]

    supported_extension = set(Image.registered_extensions())
    image_content_minimum_size = 50

    def __init__(self, url, timeout=60):
        self.start = time.time()
        self.url = url
        self.timeout = timeout
        self.extension = self._get_extension()
        self.image_content = self.get_image_content()

    def _is_timeout(self):
        now = time.time()
        duration = now - self.start
        if duration > self.timeout:
            return True
        return False

    def _is_supported(self):
        """
        Supported Format:[
        '.blp', '.bmp', '.dib', '.bufr', '.cur', '.pcx', '.dcx', '.dds',
        '.ps', '.eps', '.fit', '.fits', '.fli', '.flc', '.ftc', '.ftu',
        '.gbr', '.gif', '.grib', '.h5', '.hdf', '.png', '.apng', '.jp2',
        '.j2k', '.jpc', '.jpf', '.jpx', '.j2c', '.icns', '.ico', '.im',
        '.iim', '.tif', '.tiff', '.jfif', '.jpe', '.jpg', '.jpeg', '.mpg',
        '.mpeg', '.mpo', '.msp', '.palm', '.pcd', '.pdf', '.pxr', '.pbm',
        '.pgm', '.ppm', '.pnm', '.psd', '.bw', '.rgb', '.rgba', '.sgi',
        '.ras', '.tga', '.icb', '.vda', '.vst', '.webp', '.wmf', '.emf',
        '.xbm', '.xpm']
        """
        if self.extension in self.supported_extension:
            return True
        return False

    def _get_extension(self):
        split_url = os.path.splitext(self.url)
        if len(split_url) < 2:
            return None
        extension = split_url[-1]
        if extension:
            return extension.lower()
        return None

    def _request_image_content(self):
        while True:
            timeout = self.timeout
            url = self.url
            start = self.start
            if self._is_timeout():
                DebugTool.error(f'REQUEST TIMEOUT ({timeout} Secs.): {url}')
                response_content = None
                break
            try:
                response = requests.get(url)
                response_content = response.content
                break
            except MaxRetryError as e:
                DebugTool.error(e)
                response_content = None
                break
            except Exception as e:
                DebugTool.error(e)
                time.sleep(0.5)
        return response_content

    def get_image_content(self):
        if not self._is_supported:
            DebugTool.info(f'{self.extension} IS NOT SUPPORTED: {self.url}')
            return None
        image_content = self._request_image_content()
        minimum_size = self.image_content_minimum_size
        if len(image_content) < self.image_content_minimum_size:
            DebugTool.info(
                f'IMAGE LENGTH IS TOO SHORT: {len(image_content)} {self.url}')
            return None
        if b'Error' in image_content:
            #  error URL request from FOTMOB
            DebugTool.info(f'IMAGE CONTENT NOT FOUND: {self.url}')
            return None
        if b'Not Found' in image_content:
            #  error URL request from GOAL
            DebugTool.info(f'IMAGE CONTENT NOT FOUND: {self.url}')
            return None
        return image_content
Example #29
0
class ImageProcessor:
    """
        Aim to convert, download image and get converted content as base64 into database
    """

    PREFIX = ImagePathProcessor.PREFIX

    EXTENSION_DICT = Image.registered_extensions()

    SCREEN_WIDTH = os.get_terminal_size(0)[0]

    def __init__(self,
                 image_content,
                 mode,
                 extension,
                 download_image=False,
                 path=None,
                 prefix=None,
                 target_id=None):
        self.image_content = image_content
        self.mode = mode
        self.extension = extension

        self.image = self.get_image()
        self.image_base64 = self.get_image_base64()

        self.download_image = download_image
        self.path = path
        self.prefix = prefix
        self.target_id = target_id

        self._validate()
        self.filename = self.get_filename()
        self.download()

    ## CHECK VALIDATE

    def _validate(self):
        """
        檢查
        若請求下載,必須包含 path, prefix, target_id 且 prefix 必須包含在 ['league', 'team', 'player', 'news']
        """
        if self.download_image:
            if not self.path:
                error_info = f' "path" is required if download image! '
                raise Exception(f'\n{error_info:-^{self.SCREEN_WIDTH}}')
            if not self.prefix:
                error_info = f' "prefix" is required if download image! '
                raise Exception(f'\n{error_info:-^{self.SCREEN_WIDTH}}')
            if not self.target_id:
                error_info = f' "target_id" is required if download image! '
                raise Exception(f'\n{error_info:-^{self.SCREEN_WIDTH}}')
        if self.prefix.lower() not in self.PREFIX:
            error_info = f' INVALID FILENAME ATTRIBUTE: "{self.prefix}" '
            raise Exception(f'\n{error_info:-^{self.SCREEN_WIDTH}}')

    ## PARSE method

    def _parse_extension(self):
        '''
        convert extension
        '''
        extension = str(self.extension)
        extension = extension.lower()
        extension = extension.lstrip('.')
        return self.EXTENSION_DICT.get(f'.{extension}', None)

    ## CONVERT method

    @staticmethod
    def _convert_mode(image, mode):
        """
        Returns PIL image object with specific mode.
        :image: The requested PIL image object.
        :mode: An optional parameter. This can be one of
            ['L', 'P', ,'RGBX', ,'RGBA', ,'CMYK', 'I;16', ,'I;16L', ,'I;16B']
            and the default value is 'RGBA'
        :returns: An :class:'~PIL.Image.Image' object.
        """
        if image.mode != mode:
            return image.convert(mode)
        return image

    @staticmethod
    def convert_base64_to_content(image_base64):
        """
        convert BASE64 into bytes
        """
        return base64.b64decode(image_base64)

    @staticmethod
    def convert_content_to_base64(image_content):
        """
        convert bytes into a BASE64 BLOB string
        """
        return base64.b64encode(image_content)

    @classmethod
    def convert_content_to_image(cls, image_content, mode):
        """
        convert bytes into PIL image object.
        The mode can be one of
        ['L', 'P', ,'RGBX', ,'RGBA', ,'CMYK', 'I;16', ,'I;16L', ,'I;16B']
        """
        image = Image.open(BytesIO(image_content))
        return cls._convert_mode(image=image, mode=mode)

    def convert_image_to_content(self):
        """
        convert PIL image object into bytes
        """
        extension = self._parse_extension()
        if not extension:
            error_info = f' UNSUPPORTED EXTENSION: {self.extension} '
            raise Exception(f'\n{error_info:-^{self.SCREEN_WIDTH}}')
        canvas = BytesIO()
        self.image.save(canvas, format=extension)
        image_bytes = canvas.getvalue()
        return image_bytes

    ## GET method

    def get_image_base64(self):
        image_content = self.convert_image_to_content()
        return self.convert_content_to_base64(image_content=image_content)

    def get_filename(self):
        filename = ImagePathProcessor.get_filename(prefix=self.prefix.lower(),
                                                   target_id=self.target_id,
                                                   extension=self.extension)
        return filename

    def get_image(self):
        return self.convert_content_to_image(image_content=self.image_content,
                                             mode=self.mode)

    ## ACTIONS

    @staticmethod
    def save_image(image, path, filename):
        """
        save PIL image object as a file
        """
        try:
            image.save(os.path.join(path, filename))
            return True
        except Exception as e:
            DebugTool.error(e, msg=f'path: {path} | filename: {filename}')
            return False

    def download(self):
        if not self.download_image:
            return False
        return self.save_image(image=self.image,
                               path=self.path,
                               filename=self.filename)

    @classmethod
    def export(cls, image_content, mode, path, filename):
        # image_content = cls.convert_base64_to_content(image_base64=image_base64)
        # 不需先轉 base64
        image = cls.convert_content_to_image(image_content=image_content,
                                             mode=mode)
        return cls.save_image(image=image, path=path, filename=filename)
Example #30
0
def is_img(name):
    if name.lower() in Image.registered_extensions():
        return True
    return False
Example #31
0
    def get(self, url):
        parse = reqparse.RequestParser()
        parse.add_argument('width', type=int, help='wrong width', default=300)
        parse.add_argument('height',
                           type=int,
                           help='wrong height',
                           default=300)
        parse.add_argument('share_token', type=str, default='')
        args = parse.parse_args()
        # 获取当前文件夹id
        width = args.get('width')
        height = args.get('height')
        share_token = args.get('share_token')

        shareobj = ShareTable.query.filter_by(share_url=url).first()
        if shareobj is None:
            response = make_response(
                jsonify(code=11, message='node not exist, query fail'))
            return response
        file_node = FileNode.query.filter_by(id=shareobj.file_id).first()
        if file_node is None:
            response = make_response(
                jsonify(code=11, message='node not exist, query fail'))
            return response
        if shareobj.share_token == '' or share_token == shareobj.share_token:
            if shareobj.share_end_time < int(time.time()):
                response = make_response(
                    jsonify(code=42, message='out of date'))
                return response
            if file_node.type_of_node in config['IMG_TYPE']:
                parent_id = file_node.parent_id
                filename = file_node.filename
                node_type = file_node.type_of_node
                # 生成文件名的 hash
                actual_filename = generate_file_name(parent_id, filename)
                # 结合 UPLOAD_FOLDER 得到最终文件的存储路径
                target_file = os.path.join(os.path.expanduser(UPLOAD_FOLDER),
                                           actual_filename)
                if os.path.exists(target_file):
                    try:
                        with Image.open(target_file, mode='r') as img_data:
                            # img_data = Image.open(target_file)
                            img_data.thumbnail((width, height))

                            fp = io.BytesIO()
                            format = Image.registered_extensions()['.' +
                                                                   node_type]
                            img_data.save(fp, format)

                            response = make_response(fp.getvalue())
                            response.headers[
                                'Content-Type'] = 'image/' + node_type
                            return response
                    except:
                        response = make_response(
                            jsonify(code=24, message='preview not allowed'))
                        return response
                else:
                    response = make_response(
                        jsonify(code=22, message='file not exist'))
                    return response
            else:
                response = make_response(
                    jsonify(code=24, message='preview not allowed'))
                return response
        else:
            response = make_response(
                jsonify(code=41, message='wrong share_token'))
            return response