示例#1
0
def optimize_png_file(f, o=None):
    """
    Use pngquant for optimize PNG-image.
    f - path to input image file or file-object.
    o - path to output image file or file-object for save result.
    NOTICE: f and o can not be of different type
    """
    if isinstance(f, basestring):
        if o is None:
            o = f
        else:
            assert isinstance(o, basestring)
        try:
            subprocess.check_call(['pngquant', '--force', '--output', o, f])
        except subprocess.CalledProcessError:
            return False
        return True
    if not hasattr(f, 'read'):
        raise RuntimeError
    if o is None:
        o = f
    else:
        if not hasattr(f, 'write'):
            raise RuntimeError
    f.seek(0)
    try:
        p = subprocess.Popen(['pngquant', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        r = p.communicate(f.read())[0]
    except IOError:
        r = None
    if r:
        truncate_file(o)
        o.write(r)
        return True
    return False
示例#2
0
def optimize_png_file(f, o=None):
    """
    Use pngquant for optimize PNG-image.
    f - path to input image file or file-object.
    o - path to output image file or file-object for save result.
    NOTICE: f and o can not be of different type
    """
    if isinstance(f, basestring):
        if o is None:
            o = f
        else:
            assert isinstance(o, basestring)
        try:
            subprocess.check_call(['pngquant', '--force', '--output', o, f])
        except subprocess.CalledProcessError:
            return False
        return True
    if not hasattr(f, 'read'):
        raise RuntimeError
    if o is None:
        o = f
    else:
        if not hasattr(f, 'write'):
            raise RuntimeError
    f.seek(0)
    try:
        p = subprocess.Popen(['pngquant', '-'],
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE)
        r = p.communicate(f.read())[0]
    except IOError:
        r = None
    if r:
        truncate_file(o)
        o.write(r)
        return True
    return False
示例#3
0
def adjust_image(f,
                 max_size=(800, 800),
                 new_format=None,
                 jpeg_quality=90,
                 fill=False,
                 stretch=False,
                 return_new_image=False,
                 force_jpeg_save=True):
    """
    Підганяє зображення під параметри.
    max_size - максимальний розмір картинки. один з розмірів може бути None (авто)
    new_format - формат файлу (jpeg, png, gif). якщо None, тоді буде використаний формат оригіналу
    jpeg_quality - якість JPEG
    fill - чи зображення має бути заповненим при обрізці (інакше буде вписане)
    stretch - чи розтягувати, якщо картинка замаленька
    return_new_image - якщо True, тоді буде повертатись новий об'єкт StringIO картинки. Інакше bool, чи файл змінювався.
    force_jpeg_save - якщо True, тоді якщо файл JPEG, то він буде перезбережений в будь-якому випадку
    """
    assert isinstance(max_size, (list, tuple)) and len(max_size) == 2
    assert 0 < jpeg_quality <= 100
    if new_format:
        new_format = new_format.lower()
        if new_format not in ('jpeg', 'png', 'gif'):
            raise RuntimeError('Invalid new_format value.')
    f.seek(0)
    img = Image.open(f)
    if ((new_format == 'jpeg' and img.mode != 'RGB') or
        (new_format is None and img.format == 'JPEG' and img.mode != 'RGB')):
        do_convert = True
        if dju_settings.DJU_IMG_CONVERT_JPEG_TO_RGB:
            img = get_image_as_rgb(f)
            if img is not None:
                do_convert = False
        if do_convert:
            current_format = img.format
            img = img.convert('RGB')
            img.format = current_format
    max_width, max_height = max_size
    img_width, img_height = img.size
    img_format = img.format.lower()
    ch_size = ch_format = False
    if max_width is None:
        max_width = int(((img_width / float(img_height)) * max_height))
    elif max_height is None:
        max_height = int(((img_height / float(img_width)) * max_width))
    if (img_width, img_height) != (max_width, max_height):
        tasks = []
        if fill:
            if (img_width < max_width
                    or img_height < max_height) and not stretch:
                k = max(max_width / float(img_width),
                        max_height / float(img_height))
                w, h = max_width / k, max_height / k
                left, top = int((img_width - w) / 2.), int(
                    (img_height - h) / 2.)
                tasks.append(
                    ('crop', ((left, top, int(left + w), int(top + h)), ), {}))
            else:
                k = min(img_width / float(max_width),
                        img_height / float(max_height))
                w, h = img_width / k, img_height / k
                tasks.append(('resize', ((int(w), int(h)), Image.LANCZOS), {}))
                left, top = int((w - max_width) / 2.), int(
                    (h - max_height) / 2.)
                tasks.append(('crop', ((left, top, left + max_width,
                                        top + max_height), ), {}))
        elif ((img_width > max_width or img_height > max_height) or
              (img_width < max_width and img_height < max_height and stretch)):
            k = max(img_width / float(max_width),
                    img_height / float(max_height))
            w, h = int(img_width / k), int(img_height / k)
            tasks.append(('resize', ((w, h), Image.LANCZOS), {}))
        for img_method, method_args, method_kwargs in tasks:
            if ((img_method == 'resize'
                 and method_args[0] == (img_width, img_height)) or
                (img_method == 'crop'
                 and method_args[0] == (0, 0, img.size[0], img.size[1]))):
                continue
            img = getattr(img, img_method)(*method_args, **method_kwargs)
            ch_size = True
    if new_format and new_format != img_format:
        img_format = new_format
        ch_format = True
    if not ch_format and img_format == 'jpeg' and force_jpeg_save:
        ch_format = True
    if return_new_image:
        t = StringIO()
        _save_img(img,
                  t,
                  img_format=img_format,
                  quality=jpeg_quality,
                  progressive=True,
                  optimize=True)
        return t
    if ch_size or ch_format:
        img.load()
        truncate_file(f)
        _save_img(img,
                  f,
                  img_format=img_format,
                  quality=jpeg_quality,
                  progressive=True,
                  optimize=True)
        if isinstance(f, UploadedFile):
            f.seek(0, 2)
            f.size = f.tell()
            set_uploaded_file_content_type_and_file_ext(f, img_format)
    return ch_size or ch_format
示例#4
0
        except IOError, e:
            last_error = e
    if last_error:
        raise last_error
    if image_get_format(f) == 'jpeg' and dju_settings.DJU_IMG_USE_JPEGTRAN:
        f.seek(0)
        try:
            p = subprocess.Popen(
                ['jpegtran', '-copy', 'none', '-optimize', '-progressive'],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE)
            r = p.communicate(f.read())[0]
        except IOError:
            r = None
        if r:
            truncate_file(f)
            f.write(r)


def get_image_as_rgb(f):
    f.seek(0)
    try:
        p = subprocess.Popen(['convert', '-colorspace', 'rgb', '-', '-'],
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE)
        r = p.communicate(f.read())[0]
    except IOError:
        r = None
    if r:
        return Image.open(StringIO(r))
示例#5
0
def adjust_image(f, max_size=(800, 800), new_format=None, jpeg_quality=90, fill=False, stretch=False,
                 return_new_image=False, force_jpeg_save=True):
    """
    Підганяє зображення під параметри.
    max_size - максимальний розмір картинки. один з розмірів може бути None (авто)
    new_format - формат файлу (jpeg, png, gif). якщо None, тоді буде використаний формат оригіналу
    jpeg_quality - якість JPEG
    fill - чи зображення має бути заповненим при обрізці (інакше буде вписане)
    stretch - чи розтягувати, якщо картинка замаленька
    return_new_image - якщо True, тоді буде повертатись новий об'єкт StringIO картинки. Інакше bool, чи файл змінювався.
    force_jpeg_save - якщо True, тоді якщо файл JPEG, то він буде перезбережений в будь-якому випадку
    """
    assert isinstance(max_size, (list, tuple)) and len(max_size) == 2
    assert 0 < jpeg_quality <= 100
    if new_format:
        new_format = new_format.lower()
        if new_format not in ('jpeg', 'png', 'gif'):
            raise RuntimeError('Invalid new_format value.')
    f.seek(0)
    img = Image.open(f)
    if ((new_format == 'jpeg' and img.mode != 'RGB') or
            (new_format is None and img.format == 'JPEG' and img.mode != 'RGB')):
        do_convert = True
        if dju_settings.DJU_IMG_CONVERT_JPEG_TO_RGB:
            img = get_image_as_rgb(f)
            if img is not None:
                do_convert = False
        if do_convert:
            current_format = img.format
            img = img.convert('RGB')
            img.format = current_format
    max_width, max_height = max_size
    img_width, img_height = img.size
    img_format = img.format.lower()
    ch_size = ch_format = False
    if max_width is None:
        max_width = int(((img_width / float(img_height)) * max_height))
    elif max_height is None:
        max_height = int(((img_height / float(img_width)) * max_width))
    if (img_width, img_height) != (max_width, max_height):
        tasks = []
        if fill:
            if (img_width < max_width or img_height < max_height) and not stretch:
                k = max(max_width / float(img_width), max_height / float(img_height))
                w, h = max_width / k, max_height / k
                left, top = int((img_width - w) / 2.), int((img_height - h) / 2.)
                tasks.append(('crop', ((left, top, int(left + w), int(top + h)),), {}))
            else:
                k = min(img_width / float(max_width), img_height / float(max_height))
                w, h = img_width / k, img_height / k
                tasks.append(('resize', ((int(w), int(h)), Image.LANCZOS), {}))
                left, top = int((w - max_width) / 2.), int((h - max_height) / 2.)
                tasks.append(('crop', ((left, top, left + max_width, top + max_height),), {}))
        elif ((img_width > max_width or img_height > max_height) or
                (img_width < max_width and img_height < max_height and stretch)):
            k = max(img_width / float(max_width), img_height / float(max_height))
            w, h = int(img_width / k), int(img_height / k)
            tasks.append(('resize', ((w, h), Image.LANCZOS), {}))
        for img_method, method_args, method_kwargs in tasks:
            if ((img_method == 'resize' and method_args[0] == (img_width, img_height)) or
                    (img_method == 'crop' and method_args[0] == (0, 0, img.size[0], img.size[1]))):
                continue
            img = getattr(img, img_method)(*method_args, **method_kwargs)
            ch_size = True
    if new_format and new_format != img_format:
        img_format = new_format
        ch_format = True
    if not ch_format and img_format == 'jpeg' and force_jpeg_save:
        ch_format = True
    if return_new_image:
        t = StringIO()
        _save_img(img, t, img_format=img_format, quality=jpeg_quality, progressive=True, optimize=True)
        return t
    if ch_size or ch_format:
        img.load()
        truncate_file(f)
        _save_img(img, f, img_format=img_format, quality=jpeg_quality, progressive=True, optimize=True)
        if isinstance(f, UploadedFile):
            f.seek(0, 2)
            f.size = f.tell()
            set_uploaded_file_content_type_and_file_ext(f, img_format)
    return ch_size or ch_format
示例#6
0
                last_error = None
                break
        except IOError, e:
            last_error = e
    if last_error:
        raise last_error
    if image_get_format(f) == 'jpeg' and dju_settings.DJU_IMG_USE_JPEGTRAN:
        f.seek(0)
        try:
            p = subprocess.Popen(['jpegtran', '-copy', 'none', '-optimize', '-progressive'],
                                 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            r = p.communicate(f.read())[0]
        except IOError:
            r = None
        if r:
            truncate_file(f)
            f.write(r)


def get_image_as_rgb(f):
    f.seek(0)
    try:
        p = subprocess.Popen(['convert', '-colorspace', 'rgb', '-', '-'],
                             stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        r = p.communicate(f.read())[0]
    except IOError:
        r = None
    if r:
        return Image.open(StringIO(r))