예제 #1
0
def build_image(file,
                size,
                pre_key,
                crop=False,
                quality=90,
                cache=False,
                unique_key=None,
                constrain=False):
    """
    Builds a resized image based off of the original image.
    """
    try:
        quality = int(quality)
    except TypeError:
        quality = 90

    if settings.USE_S3_STORAGE:
        content = read_media_file_from_s3(file)
        image = Image.open(StringIO(content))
    else:
        if hasattr(file, 'path') and exists(file.path):
            image = Image.open(file.path)  # get image
        else:
            raise Http404

    image = apply_orientation(image)

    image_options = {'quality': quality}
    if image.format == 'GIF':
        image_options['transparency'] = 0

    format = image.format
    if image.format in ('GIF', 'PNG'):
        if image.mode != "RGBA":
            image = image.convert("RGBA")
        image.format = format  # this is lost in conversion

    elif image.format == 'JPEG':
        # handle infamous error
        # IOError: cannot write mode P as JPEG
        if image.mode != "RGB":
            image = image.convert("RGB")

    if crop:
        image = image_rescale(image, size)  # thumbnail image
    else:
        format = image.format
        image = image.resize(size, Image.ANTIALIAS)  # resize image
        image.format = format

    binary = get_image_binary(image, **image_options)

    if cache:
        key = generate_image_cache_key(file, size, pre_key, crop, unique_key,
                                       quality, constrain)
        django_cache.add(key, binary,
                         60 * 60 * 24 * 30)  # cache for 30 days #issue/134

    return binary
예제 #2
0
파일: utils.py 프로젝트: tendenci/tendenci
def build_image(file, size, pre_key, crop=False, quality=90, cache=False, unique_key=None, constrain=False):
    """
    Builds a resized image based off of the original image.
    """
    try:
        quality = int(quality)
    except TypeError:
        quality = 90

    if settings.USE_S3_STORAGE:
        content = read_media_file_from_s3(file)
        image = Image.open(BytesIO(content))
    else:
        if hasattr(file, 'path') and exists(file.path):
            image = Image.open(file.path)  # get image
        else:
            raise Http404
        
    image = apply_orientation(image)

    image_options = {'quality': quality}
    if image.format == 'GIF':
        image_options['transparency'] = 0

    format = image.format
    if image.format in ('GIF', 'PNG'):
        if image.mode != "RGBA":
            image = image.convert("RGBA")
        image.format = format  # this is lost in conversion

    elif image.format == 'JPEG':
        # handle infamous error
        # IOError: cannot write mode P as JPEG
        if image.mode != "RGB":
            image = image.convert("RGB")

    if crop:
        image = image_rescale(image, size)  # thumbnail image
    else:
        format = image.format
        image = image.resize(size, Image.ANTIALIAS)  # resize image
        image.format = format

    binary = get_image_binary(image, **image_options)

    if cache:
        key = generate_image_cache_key(file, size, pre_key, crop, unique_key, quality, constrain)
        django_cache.add(key, binary, 60 * 60 * 24 * 30)  # cache for 30 days #issue/134

    return binary
예제 #3
0
파일: utils.py 프로젝트: eloyz/tendenci
def build_image(file,
                size,
                pre_key,
                crop=False,
                quality=90,
                cache=False,
                unique_key=None):
    """
    Builds a resized image based off of the original image.
    """

    try:
        quality = int(quality)
    except:
        quality = 90

    if settings.USE_S3_STORAGE:
        content = read_media_file_from_s3(file)
        image = Image.open(StringIO(content))
    else:
        if hasattr(file, 'path') and exists(file.path):
            image = Image.open(file.path)  # get image
        else:
            raise Http404

    # handle infamous error
    # IOError: cannot write mode P as JPEG
    if image.mode != "RGB":
        image = image.convert("RGB")

    if crop:
        image = image_rescale(image, size)  # thumbnail image
    else:
        image = image.resize(size, Image.ANTIALIAS)  # resize image

    # mission: get binary
    output = StringIO()
    image.save(output, "JPEG", quality=quality)
    binary = output.getvalue()  # mission accomplished
    output.close()

    if cache:
        key = generate_image_cache_key(file, size, pre_key, crop, unique_key,
                                       quality)
        django_cache.add(key, binary,
                         60 * 60 * 24 * 30)  # cache for 30 days #issue/134

    return binary
예제 #4
0
파일: utils.py 프로젝트: legutierr/tendenci
def build_image(file, size, pre_key, crop=False, quality=90, cache=False, unique_key=None):
    """
    Builds a resized image based off of the original image.
    """

    try:
        quality = int(quality)
    except:
        quality = 90

    if settings.USE_S3_STORAGE:
        content = read_media_file_from_s3(file)
        image = Image.open(StringIO(content))
    else:
        if hasattr(file, 'path') and exists(file.path):
            image = Image.open(file.path)  # get image
        else:
            raise Http404

    # handle infamous error
    # IOError: cannot write mode P as JPEG
    if image.mode != "RGB":
        image = image.convert("RGB")

    if crop:
        image = image_rescale(image, size)  # thumbnail image
    else:
        image = image.resize(size, Image.ANTIALIAS)  # resize image

    # mission: get binary
    output = StringIO()
    image.save(output, "JPEG", quality=quality)
    binary = output.getvalue()  # mission accomplished
    output.close()

    if cache:
        key = generate_image_cache_key(file, size, pre_key, crop, unique_key, quality)
        django_cache.add(key, binary, 60 * 60 * 24 * 30)  # cache for 30 days #issue/134

    return binary
예제 #5
0
def details(request,
            id,
            size=None,
            crop=False,
            quality=90,
            download=False,
            constrain=False,
            template_name="files/details.html"):
    """
    Return an image response after paramters have been applied.
    """
    file = get_object_or_404(File, pk=id)
    file_path = unicode(file.file)
    if file.type() == 'image' and default_storage.exists(file_path):
        image = read_media_file_from_s3(file_path)
        # if image not rendered; quit
        if not image:
            raise Http404

        response = HttpResponse(image, content_type=file.mime_type())
        # return response
        if file.get_name().endswith(file.ext()):
            response['Content-Disposition'] = 'filename="%s"' % file.get_name()
        return response

    cache_key = generate_image_cache_key(file=id,
                                         size=size,
                                         pre_key=FILE_IMAGE_PRE_KEY,
                                         crop=crop,
                                         unique_key=id,
                                         quality=quality,
                                         constrain=constrain)

    cached_image = cache.get(cache_key)

    if cached_image:
        if file.type() != 'image':
            # log an event
            EventLog.objects.log(instance=file)
        return redirect(
            '%s%s' % (get_setting('site', 'global', 'siteurl'), cached_image))

    # basic permissions
    if not has_view_perm(request.user, 'files.view_file', file):
        raise Http403

    # extra permission
    if not file.is_public:
        if not request.user.is_authenticated():
            raise Http403

    # if string and digit convert to integer
    if isinstance(quality, basestring) and quality.isdigit():
        quality = int(quality)

    # get image binary
    try:
        data = file.file.read()
        file.file.close()
    except IOError:  # no such file or directory
        raise Http404

    if download:  # log download
        attachment = u'attachment;'
        EventLog.objects.log(
            **{
                'event_id':
                185000,
                'event_data':
                '%s %s (%d) dowloaded by %s' %
                (file.type(), file._meta.object_name, file.pk, request.user),
                'description':
                '%s downloaded' % file._meta.object_name,
                'user':
                request.user,
                'request':
                request,
                'instance':
                file,
            })
    else:  # log view
        attachment = u''
        if file.type() != 'image':
            EventLog.objects.log(
                **{
                    'event_id':
                    186000,
                    'event_data':
                    '%s %s (%d) viewed by %s' %
                    (file.type(), file._meta.object_name, file.pk,
                     request.user),
                    'description':
                    '%s viewed' % file._meta.object_name,
                    'user':
                    request.user,
                    'request':
                    request,
                    'instance':
                    file,
                })

    # if image size specified
    if file.type() == 'image' and size:  # if size specified

        if file.ext() in ('.tif', '.tiff'):
            raise Http404  # tifs cannot (currently) be viewed via browsers

        size = [int(s) if s.isdigit() else 0 for s in size.split('x')]
        size = aspect_ratio(file.image_dimensions(), size, constrain)

        # check for dimensions
        # greater than zero
        if not all(size):
            raise Http404

        # gets resized image from cache or rebuilds
        image = get_image(file.file,
                          size,
                          FILE_IMAGE_PRE_KEY,
                          cache=True,
                          crop=crop,
                          quality=quality,
                          unique_key=None)
        response = HttpResponse(content_type=file.mime_type())
        response['Content-Disposition'] = '%s filename="%s"' % (
            attachment, file.get_name())

        params = {'quality': quality}
        if image.format == 'GIF':
            params['transparency'] = 0

        image.save(response, image.format, **params)

        if file.is_public_file():
            file_name = "%s%s" % (file.get_name(), ".jpg")
            file_path = 'cached%s%s' % (request.path, file_name)
            default_storage.delete(file_path)
            default_storage.save(file_path, ContentFile(response.content))
            full_file_path = "%s%s" % (settings.MEDIA_URL, file_path)
            cache.set(cache_key, full_file_path)
            cache_group_key = "files_cache_set.%s" % file.pk
            cache_group_list = cache.get(cache_group_key)

            if cache_group_list is None:
                cache.set(cache_group_key, [cache_key])
            else:
                cache_group_list += [cache_key]
                cache.set(cache_group_key, cache_group_list)

        return response

    if file.is_public_file():
        cache.set(cache_key, file.get_file_public_url())
        # set_s3_file_permission(file.file, public=True)
        cache_group_key = "files_cache_set.%s" % file.pk
        cache_group_list = cache.get(cache_group_key)

        if cache_group_list is None:
            cache.set(cache_group_key, [cache_key])
        else:
            cache_group_list += cache_key
            cache.set(cache_group_key, cache_group_list)

    # set mimetype
    if file.mime_type():
        response = HttpResponse(data, content_type=file.mime_type())
    else:
        raise Http404

    # return response
    if file.get_name().endswith(file.ext()):
        response['Content-Disposition'] = '%s filename="%s"' % (
            attachment, file.get_name())
    else:
        response['Content-Disposition'] = '%s filename="%s"' % (
            attachment, file.get_name_ext())
    return response
예제 #6
0
def get_image_from_path(path):
    if settings.USE_S3_STORAGE:
        content = read_media_file_from_s3(path)
        return Image.open(StringIO(content))
    return Image.open(path)