def photo_dwnl(request, photo_id, **kwargs): photo = get_object_or_404(Photo.objects.all(), pk=photo_id) path = photo.image.path # Get file path if not os.path.isfile(path): raise Http404 content_type = mimetypes.guess_type(path)[0] try: wm = Watermark.objects.get(name='main', is_active=True) except Watermark.DoesNotExist: file = open(path, 'r') length = os.path.getsize(path) # not FileField instance else: try: target = Image.open(photo.image.path) mark = Image.open(wm.image.path) except IOError: file = open(path, 'r') length = os.path.getsize(path) # not FileField instance else: pos = determine_position('br', target, mark) file = StringIO.StringIO() target = watermark(target, mark, pos, opacity=1) target.save(file, format='JPEG') file.read = file.getvalue length = file.len response = HttpResponse(content=file.read(), content_type=content_type, mimetype='application/force-download') response['Content-Length'] = length response['Content-Disposition'] = 'attachment; filename=%s' %\ smart_str(os.path.basename(path)) # same here return response
def __call__(self, url, name, position=None, opacity=0.5, tile=False, scale=1.0, greyscale=False, rotation=0, obscure=OBSCURE, quality=QUALITY, random_position_once=RANDOM_POS_ONCE): """ Creates a watermarked copy of an image. * ``name``: This is the name of the Watermark object that you wish to apply to the image. * ``position``: There are several options. * ``R``: random placement, which is the default behavior. * ``C``: center the watermark * ``XxY`` where ``X`` is either a specific pixel position on the x-axis or a percentage of the total width of the target image and ``Y`` is a specific pixel position on the y-axis of the image or a percentage of the total height of the target image. These values represent the location of the top and left edges of the watermark. If either ``X`` or ``Y`` is a percentage, you must use a percent sign. This is not used if either one of the ``tiled`` or ``scale`` parameters are true. Examples: * ``50%x50%``: positions the watermark at the center of the image. * ``50%x100``: positions the watermark at the midpoint of the total width of the image and 100 pixels from the top of the image * ``100x50%``: positions the watermark at the midpoint of the total height of the image and 100 pixels from the left edge of the image * ``100x100``: positions the top-left corner of the watermark at 100 pixels from the top of the image and 100 pixels from the left edge of the image. * ``br``, ``bl``, ``tr``, ``tl`` where ``b`` means "bottom", ``t`` means "top", ``l`` means "left", and ``r`` means "right". This will position the watermark at the extreme edge of the original image with just enough room for the watermark to "fully show". This assumes the watermark is not as big as the original image. * ``opacity``: an integer from 0 to 100. This value represents the transparency level of the watermark when it is applied. A value of 100 means the watermark is completely opaque while a value of 0 means the watermark will be invisible. * ``tile``: ``True`` or ``False`` to specify whether or not the watermark shall be tiled across the entire image. * ``scale``: a floating-point number above 0 to specify the scaling for the watermark. If you want the watermark to be scaled to its maximum without falling off the edge of the target image, use ``F``. By default, scale is set to ``1.0``, or 1:1 scaling, meaning the watermark will be placed on the target image at its original size. * ``greyscale``: ``True`` or ``False`` to specify whether or not the watermark should be converted to a greyscale image before applying it to the target image. Default is ``False``. * ``rotation``: 0 to 359 to specify the number of degrees to rotate the watermark before applying it to the target image. Alternatively, you may set ``rotation=R`` for a random rotation value. * ``obscure``: set to ``False`` if you wish to expose the original image's filename. Defaults to ``True``. * ``quality``: the quality of the resulting watermarked image. Default is 85. """ # look for the specified watermark by name. If it's not there, go no # further try: watermark = Watermark.objects.get(name=name, is_active=True) except Watermark.DoesNotExist: log.error('Watermark "%s" does not exist... Bailing out.' % name) return url # make sure URL is a string url = str(url) basedir = '%s/watermarked' % os.path.dirname(url) base, ext = os.path.splitext(os.path.basename(url)) # open the target image file along with the watermark image target_path = self.get_url_path(url) target = Image.open(target_path) mark = Image.open(watermark.image.path) # determine the actual value that the parameters provided will render random_position = bool(position is None or str(position).lower() == 'r') scale = utils.determine_scale(scale, target, mark) rotation = utils.determine_rotation(rotation, mark) pos = utils.determine_position(position, target, mark) # see if we need to create only one randomly positioned watermarked # image if not random_position or \ (not random_position_once and random_position): log.debug('Generating random position for watermark each time') position = pos else: log.debug('Random positioning watermark once') params = { 'position': position, 'opacity': opacity, 'scale': scale, 'tile': tile, 'greyscale': greyscale, 'rotation': rotation, 'base': base, 'ext': ext, 'quality': quality, 'watermark': watermark.id, 'opacity_int': int(opacity * 100), 'left': pos[0], 'top': pos[1], } log.debug('Params: %s' % params) wm_name = self.watermark_name(mark, **params) wm_url = self.watermark_path(basedir, base, ext, wm_name, obscure) wm_path = self.get_url_path(wm_url) log.debug('Watermark name: %s; URL: %s; Path: %s' % ( wm_name, wm_url, wm_path )) # see if the image already exists on the filesystem. If it does, use # it. if os.access(wm_path, os.R_OK): # see if the Watermark object was modified since the file was # created modified = datetime.fromtimestamp(os.path.getmtime(wm_path)) # only return the old file if things appear to be the same if modified >= watermark.date_updated: log.info('Watermark exists and has not changed. Bailing out.') return wm_url # make sure the position is in our params for the watermark params['position'] = pos self.create_watermark(target, mark, wm_path, **params) # send back the URL to the new, watermarked image return wm_url
def __call__(self, url, name, position=None, opacity=0.5, tile=False, scale=1.0, greyscale=False, rotation=0, obscure=OBSCURE_ORIGINAL, quality=QUALITY, random_position_once=RANDOM_POSITION_ONCE): """ Creates a watermarked copy of an image. * ``name``: This is the name of the Watermark object that you wish to apply to the image. * ``position``: There are several options. * ``R``: random placement, which is the default behavior. * ``C``: center the watermark * ``XxY`` where ``X`` is either a specific pixel position on the x-axis or a percentage of the total width of the target image and ``Y`` is a specific pixel position on the y-axis of the image or a percentage of the total height of the target image. These values represent the location of the top and left edges of the watermark. If either ``X`` or ``Y`` is a percentage, you must use a percent sign. This is not used if either one of the ``tiled`` or ``scale`` parameters are true. Examples: * ``50%x50%``: positions the watermark at the center of the image. * ``50%x100``: positions the watermark at the midpoint of the total width of the image and 100 pixels from the top of the image * ``100x50%``: positions the watermark at the midpoint of the total height of the image and 100 pixels from the left edge of the image * ``100x100``: positions the top-left corner of the watermark at 100 pixels from the top of the image and 100 pixels from the left edge of the image. * ``br``, ``bl``, ``tr``, ``tl`` where ``b`` means "bottom", ``t`` means "top", ``l`` means "left", and ``r`` means "right". This will position the watermark at the extreme edge of the original image with just enough room for the watermark to "fully show". This assumes the watermark is not as big as the original image. * ``opacity``: an integer from 0 to 100. This value represents the transparency level of the watermark when it is applied. A value of 100 means the watermark is completely opaque while a value of 0 means the watermark will be invisible. * ``tile``: ``True`` or ``False`` to specify whether or not the watermark shall be tiled across the entire image. * ``scale``: a floating-point number above 0 to specify the scaling for the watermark. If you want the watermark to be scaled to its maximum without falling off the edge of the target image, use ``F``. By default, scale is set to ``1.0``, or 1:1 scaling, meaning the watermark will be placed on the target image at its original size. * ``greyscale``: ``True`` or ``False`` to specify whether or not the watermark should be converted to a greyscale image before applying it to the target image. Default is ``False``. * ``rotation``: 0 to 359 to specify the number of degrees to rotate the watermark before applying it to the target image. Alternatively, you may set ``rotation=R`` for a random rotation value. * ``obscure``: set to ``False`` if you wish to expose the original image's filename. Defaults to ``True``. * ``quality``: the quality of the resulting watermarked image. Default is 85. """ # look for the specified watermark by name. If it's not there, go no # further try: watermark = Watermark.objects.get(name=name, is_active=True) except Watermark.DoesNotExist: logger.error('Watermark "%s" does not exist... Bailing out.' % name) return url # make sure URL is a string url = smart_str(url) basedir = '%s/watermarked/' % os.path.dirname(url) original_basename, ext = os.path.splitext(os.path.basename(url)) # open the target image file along with the watermark image target = Image.open(self._get_filesystem_path(url)) mark = Image.open(watermark.image.path) # determine the actual value that the parameters provided will render random_position = bool(position is None or str(position).lower() == 'r') scale = utils.determine_scale(scale, target, mark) mark = mark.resize(scale, resample=Image.ANTIALIAS) rotation = utils.determine_rotation(rotation, mark) pos = utils.determine_position(position, target, mark) # see if we need to create only one randomly positioned watermarked # image if not random_position or (not random_position_once and random_position): logger.debug('Generating random position for watermark each time') position = pos else: logger.debug('Random positioning watermark once') params = { 'position': position, 'opacity': opacity, 'scale': scale, 'tile': tile, 'greyscale': greyscale, 'rotation': rotation, 'original_basename': original_basename, 'ext': ext, 'quality': quality, 'watermark': watermark.id, 'left': pos[0], 'top': pos[1], # 'fstat': os.stat(self._get_filesystem_path(url)), } logger.debug('Params: %s' % params) fname = self.generate_filename(mark, **params) url_path = self.get_url_path(basedir, original_basename, ext, fname, obscure) fpath = self._get_filesystem_path(url_path) logger.debug('Watermark name: %s; URL: %s; Path: %s' % ( fname, url_path, fpath, )) # see if the image already exists on the filesystem. If it does, use it. if os.access(fpath, os.R_OK): # see if the ``Watermark`` object was modified since the # file was created modified = make_aware( datetime.fromtimestamp(os.path.getmtime(fpath)), get_default_timezone()) # only return the old file if things appear to be the same if modified >= watermark.date_updated: logger.info( 'Watermark exists and has not changed. Bailing out.') return url_path # make sure the position is in our params for the watermark params['position'] = pos self.create_watermark(target, mark, fpath, **params) # send back the URL to the new, watermarked image return url_path