summaryrefslogtreecommitdiff
path: root/pb/imgrid.py
diff options
context:
space:
mode:
Diffstat (limited to 'pb/imgrid.py')
-rwxr-xr-xpb/imgrid.py231
1 files changed, 231 insertions, 0 deletions
diff --git a/pb/imgrid.py b/pb/imgrid.py
new file mode 100755
index 0000000..f75ec4a
--- /dev/null
+++ b/pb/imgrid.py
@@ -0,0 +1,231 @@
+#!/usr/bin/python2.7
+import sys
+import re
+import os
+import simplejson as json
+import random
+import pb.lib.utils as utils
+from pb.config import *
+import tempfile
+
+DEFAULT_HEIGHT = 400
+DEFAULT_WIDTH = 600
+DEFAULT_LINE_COLOR = "silver"
+
+class Imgrid():
+ def __init__(self, **kwargs):
+ self.tag = "imGrid"
+ self.files_created = []
+ self.commands = [];
+ self._required_keys = [
+#{{{ required_keys
+ "width",
+ "height",
+ "linethickness",
+ "opacity",
+ "linecolor",
+ "spacing",
+ "vlines",
+ "hlines",
+ "shadow",
+ "bgimage",
+ "bgcolor",
+ "imageinstead",
+ "planebgcolor",
+ "planebgimage",
+ "swing",
+ "tilt",
+ "roll",
+ "zoom",
+ "skycolor",
+ "transition",
+ "trim",
+ "format",
+ "username"
+#}}}
+ ]
+ self.now = utils.now()
+
+ #Work out params ...
+ #note, tmpfile lib is pretty much useless here, given imagemagick's behavior with gifs (it splits them) etc...
+ #instead we're just making our own in /var/www/cache (tmpfs mounted there)
+ self.params = {}
+ for k in self._required_keys:
+ if k in kwargs:
+ if k in [ 'bgimage', 'planebgimage', 'imageinstead' ] and utils.bool_correct(kwargs[k]):
+ self.params[k] = {
+ 'url' : kwargs[k],
+ 'filename' : self._make_tempname(k),
+ 'path' : os.path.join(WORKING_DIR, self._make_tempname(k)) ,
+ }
+ try:
+ utils.download(self.params[k]['url'], self.params[k]['path'])
+ self.files_created.append(self.params[k]['path'])
+ self.params[k]['mimetype'] = utils.get_mimetype(self.params[k]['path'])
+ frames = utils.gif_frames(self.params[k]['path'])
+ if len(frames) > 1:
+ self.params[k]['path'] = random.choice(frames)
+
+ except Exception:
+ sys.stderr.write(str(e))
+ raise Exception ("BAD PARAMS");
+ elif k in [ 'skycolor', 'bgcolor', 'planebgcolor','linecolor' ]:
+ try:
+ self.params[k] = is_color(params[k])
+ except Exception:
+ raise Exception("Unable to process color for:\n{}".format(k))
+ elif k == 'opacity':
+ self.params[k] = str(float(params[k]))
+ elif k == 'zoom':
+ self.params[k] = int(float(params[k]))
+ else:
+ self.params[k] = utils.bool_correct(utils.sanitize(kwargs[k]))
+ else:
+ self.params[k] = None;
+
+ self.params = utils.dotdict(self.params)
+
+ self.basename = self._get_filename();
+
+ if not self.params.finalformat:
+ self.params.finalformat = DEFAULT_FINALFORMAT
+ self.filename = "{}.{}".format(self.basename, self.params.finalformat)
+ #final filepath is stored in self.filepath
+ self.filepath = os.path.join(WORKING_DIR, self.filename)
+
+ def _get_filename(self):
+ return "{}_{}_{}".format(
+ self.tag,
+ self.now,
+ self.params.username or ""
+ );
+
+ def _call_cmd(self, cmd):
+ try:
+ utils.call_cmd(cmd)
+ self.commands.append(" ".join(cmd));
+ except Exception:
+ raise Exception("Unable to call cmd {}".format(str(cmd)))
+
+ def _make_tempname(self, s):
+ return "IMGRIDTMP{}{}".format(self.now, s);
+
+
+ #makes a canvas file...step 1 (if not bgimage)
+ def _make_canvas(self):
+ dimensions = "{}x{}".format(
+ self.params.width or DEFAULT_WIDTH,
+ self.params.height or DEFAULT_HEIGHT
+ )
+ if self.params.bgimage:
+ return
+ bgcolor = "xc:{}".format(self.params.bgcolor or 'transparent')
+ cmd = [ BIN_CONVERT, "-size", dimensions, bgcolor, self.filepath ]
+ self._call_cmd(cmd)
+
+ #2nd step-- run grid
+ def _grid_command(self):
+ cmd = [GRID]
+ if self.params.spacing:
+ if self.params.vlines:
+ width = 2 * int(self.params.width or DEFAULT_WIDTH)
+ cmd += ["-s","{},{}".format(self.params.spacing,width)]
+ elif self.params.hlines:
+ height = 2 * int(self.params.height or DEFAULT_HEIGHT)
+ cmd += ["-s", "{},{}".format(height,self.params.spacing)]
+ else:
+ cmd += ["-s",self.params.spacing]
+ cmd += [ "-c", self.params.linecolor or DEFAULT_LINE_COLOR]
+ if self.params.linethickness: cmd += ['-t',self.params.linethickness]
+ if self.params.opacity: cmd += ['-o',self.params.opacity]
+ cmd += [ self.filepath, self.filepath ]
+ self._call_cmd(cmd)
+
+ def _shadow_cmd(self):
+ #convert 1.png \( +clone -background black -shadow 110x1+9+9 \) +swap -background none -layers merge +repage 2.png
+ cmd = [
+ BIN_CONVERT,
+ self.filepath,
+ "(","+clone","-background","black","-shadow","100x2+20+10",")",
+ "+swap","-background","none","-layers","merge","+repage" ,
+ self.filepath
+ ]
+ self._call_cmd(cmd)
+
+
+ def _threed_rotate_cmd (self):
+ #3rd step--run 3Drotate
+ cmd = [THREEDROTATE]
+ if self.params.swing: cmd += ["pan={}".format(self.params.swing)]
+ if self.params.tilt: cmd += ["tilt={}".format(self.params.tilt)]
+ if self.params.roll: cmd += ["roll={}".format(self.params.roll)]
+ if self.params.zoom:
+ cmd += ["zoom={}".format(self.params.zoom)]
+ if cmd == [THREEDROTATE]: #if nothing has been added
+ return
+ if self.params.planebgcolor and not self.params.planebgimage:
+ cmd += ["bgcolor={}".format(self.params.planebgcolor)]
+ else:
+ cmd += ["bgcolor=none"]
+ cmd += ["skycolor={}".format(self.params.skycolor or 'none')]
+ if self.params.transition: cmd += ["vp={}".format(self.params.transition)]
+ cmd += [ self.filepath, self.filepath ]
+ self._call_cmd(cmd)
+
+
+ def _trim_cmd (self):
+ cmd = [BIN_CONVERT, self.filepath, "-trim", "+repage", self.filepath]
+ self._call_cmd(cmd)
+
+ def _prepare_gridimage(self, image):
+ if image['mimetype'] != 'png':
+ cmd = [BIN_CONVERT, image['path'], self.filepath]
+ else:
+ cmd = ['cp', image['path'], self.filepath]
+ self._call_cmd(cmd)
+
+
+ def _overlay_planebgimage(self):
+ cmd = [
+ BIN_COMPOSITE,
+ "-compose", "Dst_Over", "-gravity", "center",
+ self.params.planebgimage["path"],
+ self.filepath,
+ self.filepath
+ ]
+ self._call_cmd(cmd)
+
+ def _cleanup(self):
+ if not len(self.files_created):
+ pass
+ cmd = ["rm", "-f"] + self.files_created
+ self._call_cmd(cmd)
+
+ def create(self):
+ if self.params.bgimage:
+ self._prepare_gridimage(self.params.bgimage)
+ self._grid_command()
+ elif self.params.imageinstead:
+ self._prepare_gridimage(self.params.imageinstead)
+ else:
+ self._make_canvas()
+ self._grid_command()
+ if self.params.shadow: self._shadow_cmd()
+ self._threed_rotate_cmd()
+ if self.params.planebgimage: self._overlay_planebgimage()
+ if self.params.trim: self._trim_cmd()
+ self._cleanup()
+
+if __name__ == "__main__":
+ g = Imgrid(**{
+ 'bgimage' : 'http://i.asdf.us/im/1a/imBreak_1424909483_xx_abridged___.gif',
+ 'planebgimage' : 'http://i.imgur.com/FICZtph.png',
+ 'tilt' : '30',
+ 'spacing' : '30',
+ 'hlines' : 'true',
+ 'roll' : '30',
+ 'shadow' : 'true',
+ 'trim' : 'true'
+ })
+ g.create()
+ print g.commands