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
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
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
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
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)