diff options
Diffstat (limited to 'Pb/Pattern/__init__.py')
| -rwxr-xr-x | Pb/Pattern/__init__.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/Pb/Pattern/__init__.py b/Pb/Pattern/__init__.py new file mode 100755 index 0000000..905ddf9 --- /dev/null +++ b/Pb/Pattern/__init__.py @@ -0,0 +1,172 @@ +#!/usr/bin/python2.7 +import os +import sys +import random +import re +import urllib +from Config import * +from Pb import Pb + +import simplejson as json +from PIL import Image +import uuid + +FUSE_MODE="Pin_Light" + +class Pattern(Pb): + def __init__(self, **kwargs): + self.params = {} + self.tag = "imPattern"; + self._pid = str(os.getpid()) + self.commands = []; + self._now = self.now() + self.height = "" + self.width = "" + self._required_keys = [ + #FIXME change name to username in js + #FIXME change js api + "pattern_url", + "pattern_data", + "username", + "image_url", + ] + self.files_created = [] + for k in self._required_keys: + if k in kwargs: + if k in [ 'pattern_url', 'image_url' ]: + self.params[k] = kwargs[k] + elif k == 'pattern_data': + self.params[k] = kwargs[k] #FIXME add conversion data + else: + self.params[k] = self.sanitize(kwargs[k]) + else: + self.params[k] = False; + + if not self.params['image_url']: + sys.stderr.write('no image url'); + raise ValueError + self.params = self.make_dotdict(self.params) + + self.basename, self._format = self._get_filename(); + #FIXME omit file extension for downloaded files + self._downloaded_file = os.path.join(WORKING_DIR, "IMPATTERNTMP_DL{}_{}.{}".format(self.basename, self._pid, self._format)) # same here + #lets go back to this in a second + self._pattern_file = os.path.join(WORKING_DIR, "IMPATTERNTMP_PTN{}_{}.{}".format(self.basename, self._pid, self._format)) # this + + self._download(self.params.image_url, self._downloaded_file) + + self.width, self.height = self.dimensions(self._downloaded_file) # same here + + self.filename = "{}.{}".format(self.basename, self._format) + self.filepath = os.path.join(WORKING_DIR, self.filename) + + if self.params['pattern_url']: + self._download(self.params['pattern_url'], self._pattern_file) + elif self.params['pattern_data']: + self._from_pattern_data() + else: + sys.stderr.write("pattern must be supplied as json array or as a png url") + raise ValueError; + + def _download(self, url, dest): + try: + self.download(url, dest) + self.files_created.append(dest) + except Exception as e: + sys.stderr.write(str(e)) + raise; + + def _call_cmd(self, cmd): + try: + self.call_cmd(cmd) + self.commands.append(" ".join(cmd)); + except Exception: + raise Exception("Unable to call cmd {}".format(str(cmd))) + + def _from_pattern_data(self): + def boolToColor(boolean): + if boolean: + return (0,0,0,255); + else: + return (255,255,255,255) + specs = json.loads(self.params.pattern_data); + if int(specs['width']) > 100 or int(specs['height']) > 100: + raise ValueError + sys.stderr.write("height and width need to be less than 100 px") + img = Image.new('RGBA', (int(specs['width']), int(specs['height']))); + pixels = img.load(); + for i in range(0, len(specs['matrix'])): + for j in range(0, len(specs['matrix'][i])): + pixels[j,i] = boolToColor(int(specs['matrix'][i][j])); + + img.save(self._pattern_file, "PNG") + + + def _get_filename (self): + url = self.params.image_url + name_part = ""; + file_format = ""; + if "?" in url: + url = url.split("?")[0] + if "/" in url: + url = urllib.unquote(url).replace(" ","") + name_part = url.split("/")[-1] + try: + parts = name_part.split(".") + name_part = self.sanitize(parts[-2]) + file_format = self.sanitize(parts[-1]) + if not name_part or not file_format: + sys.stderr.write( "Incompatible input file type") + raise; + except Exception as e: + sys.stderr.write( "Incompatible input file type") + raise; + else: + sys.stderr.write( "Incompatible url") + raise; + if (len(name_part) > 20): + name_part = name_part[:-20] + return "{}{}_{}_{}".format(self.tag, name_part, self._now, self.params.username or ""), file_format + + def _cleanup(self): + cmd = ["rm"]+self.files_created + self._call_cmd(cmd) + + #first step + def _make_canvas(self): + cmd = [BIN_CONVERT,"-size",self.width+"x"+self.height,"canvas:transparent", self.filepath] + self._call_cmd(cmd) + + #second step use the Canvas as a background + def _make_mask(self): + #tile the pattern pattern on the canvas + cmd = [BIN_COMPOSITE,"-tile", self._pattern_file, self.filepath, self.filepath]; + self._call_cmd(cmd) + #fuse the tiled file to create a mask + #convert thebg.gif -compose Dst_In null: thefile.gif -matte -layers composite new.gif + cmd = [BIN_CONVERT, self.filepath, "-compose", "Dst_In", "null:", + self._downloaded_file, "-matte", "-layers", "composite", self.filepath] + self._call_cmd(cmd) + + #third step + def _fuse_mask(self, fuse_mode=FUSE_MODE): + cmd = [BIN_CONVERT, "-dispose", "2", self.filepath, "null:", + self._downloaded_file, "-matte", "-compose", fuse_mode, "-layers", "composite", + self.filepath] + self._call_cmd(cmd) + + def create(self): + self._make_canvas(); + self._make_mask() + self._fuse_mask(); + +if __name__ == "__main__": + TEST_PARAMS = { + # "pattern_url" : "http://asdf.us/impattern/patterns/1.png", + "pattern_data" : '{"matrix":[["0","0","0","0","0","1","0","0","0","0"],["0","0","0","0","1","1","1","0","0","0"],["0","0","1","1","1","0","1","0","0","0"],["0","1","1","0","0","0","0","0","0","0"],["0","1","0","0","1","0","0","0","0","0"],["0","1","0","0","1","0","0","0","1","0"],["0","1","0","0","1","1","0","0","1","0"],["0","1","0","0","0","1","1","1","1","0"],["0","1","1","1","1","0","0","0","0","0"],["0","0","0","0","1","0","0","0","0","0"]],"width":"10","height":"10"}', + # "username" : "garfield", + "image_url" : "http://i.asdf.us/im/be/PinkHijab_1425078647_reye.gif", + } + p = Pattern(**TEST_PARAMS) + p.create() + |
