Josh VanderLinden avatar Josh VanderLinden committed 204a1a9

Added the option to randomly place a watermark one time. (GC #3)

Comments (0)

Files changed (3)

 ``WATERMARK_OBSCURE_ORIGINAL = False`` in your ``setings.py`` to make the
 original image file name accessible to the user.
 
+``django-watermark`` also lets you configure how random watermark positioning
+should work.  By default, a when a watermark is to be positioned randomly, only
+one watermarked image will be generated.  If you wish to generate a random
+position for an image's watermark on each request, set
+``WATERMARK_RANDOM_POSITION_ONCE`` to ``False`` in your ``settings.py``.
+
 Usage
 =====
 
   filename.
 * ``quality`` - Set this to an integer between 0 and 100 to specify the quality
   of the resulting image.  Default is 85.
+* ``random_position_once`` - Set this to 0 or 1 to specify the random
+  positioning behavior for the image's watermark.  When set to 0, the watermark
+  will be randomly placed on each request.  When set to 1, the watermark will
+  be positioned randomly on the first request, and subsequent requests will use
+  the produced image.  Default is ``True`` (random positioning only happens on
+  first request).
 
 Examples
 ========

watermarker/templatetags/watermark.py

 import logging
 import os
 import traceback
-import urlparse
 
 from django.conf import settings
 from django import template
 # determine the quality of the image after the watermark is applied
 QUALITY = getattr(settings, 'WATERMARKING_QUALITY', 85)
 OBSCURE = getattr(settings, 'WATERMARK_OBSCURE_ORIGINAL', True)
+RANDOM_POS_ONCE = getattr(settings, 'WATERMARK_RANDOM_POSITION_ONCE', True)
 
 log = logging.getLogger('watermarker')
 
 
     def __call__(self, url, name, position=None, opacity=0.5, tile=False,
                  scale=1.0, greyscale=False, rotation=0, obscure=OBSCURE,
-                 quality=QUALITY):
+                 quality=QUALITY, random_position_once=RANDOM_POS_ONCE):
         """
         Creates a watermarked copy of an image.
 
         mark = Image.open(watermark.image.path)
 
         # determine the actual value that the parameters provided will render
-        params = utils.determine_parameter_values(target, mark, position,
-                                opacity, scale, tile, greyscale, rotation)
-        params.update({
-            'base': base,
-            'ext': ext,
-            'quality': quality,
+        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(params['opacity'] * 100),
-            'left': params['position'][0],
-            'top': params['position'][1],
-        })
+            '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.
                 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
     def watermark_name(self, mark, **kwargs):
         """Comes up with a good filename for the watermarked image"""
 
-        name = '%(base)s_wm_w%(watermark)i_o%(opacity_int)i_gs%(greyscale)i_r%(rotation)i'
-        if kwargs.get('position', None):
-            name += '_p%(left)sx%(top)s'
+        params = [
+            '%(base)s',
+            'wm',
+            'w%(watermark)i',
+            'o%(opacity_int)i',
+            'gs%(greyscale)i',
+            'r%(rotation)i',
+            '_p%(position)s',
+        ]
 
         scale = kwargs.get('scale', None)
         if scale and scale != mark.size:
-            name += '_s%i' % (float(kwargs['scale'][0]) / mark.size[0] * 100)
+            params.append('_s%i' % (float(kwargs['scale'][0]) / mark.size[0] * 100))
 
         if kwargs.get('tile', None):
-            name += '_tiled'
-
-        name += '%(ext)s'
+            params.append('_tiled')
 
         # make thumbnail filename
+        name = '%s%s' % ('_'.join(params), kwargs['ext'])
         return name % kwargs
 
     def watermark_path(self, basedir, base, ext, wm_name, obscure=True):
     position = None
     obscure = OBSCURE
     quality = QUALITY
+    random_position_once = RANDOM_POS_ONCE
 
     # iterate over all parameters to see what we need to do
     for arg in args:
             obscure = bool(int(value))
         elif key == 'quality':
             quality = int(value)
+        elif key == 'random_position_once':
+            random_position_once = bool(int(value))
 
     mark = Watermarker()
     return mark(url, name, position, opacity, tile, scale, greyscale,
-                  rotation, obscure, quality)
+                  rotation, obscure, quality, random_position_once)
 
 register.filter(watermark)

watermarker/utils.py

 
     return (left, top)
 
-def determine_parameter_values(img, mark, position=(0, 0), opacity=1,
-    scale=1.0, tile=False, greyscale=False, rotation=0):
-    """
-    Examines the input parameters to determine what the actual values will be
-    for generating the watermark.
-    """
-
-    position = determine_position(position, img, mark)
-    scale = determine_scale(scale, img, mark)
-    rotation = determine_rotation(rotation, mark)
-
-    return {
-        'position':  position,
-        'opacity':   opacity,
-        'scale':     scale,
-        'tile':      tile,
-        'greyscale': greyscale,
-        'rotation':  rotation}
-
 def watermark(img, mark, position=(0, 0), opacity=1, scale=1.0, tile=False, greyscale=False, rotation=0, return_name=False, **kwargs):
     """
     Adds a watermark to an image.
 
     rotation = determine_rotation(rotation, mark)
     if rotation != 0:
-        # give soem leeway for rotation overlapping
+        # give some leeway for rotation overlapping
         new_w = mark.size[0] * 1.5
         new_h = mark.size[1] * 1.5
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.