def parseMetaFile(self, path): # Read the .meta file # it doesn't seem worth to apply caching here meta_fname = os.path.splitext(path)[0]+'.meta' meta_content = filetool.read(meta_fname) imgDict = json.loads(meta_content) # Loop through the images of the .meta file for imageId, imageSpec_ in imgDict.items(): # sort of like this: imageId : [width, height, type, combinedUri, off-x, off-y] imageObject = Image() imageObject.id = imageId imageObject = imageObject.fromMeta(imageSpec_) self.embeds.append(imageObject) return
def parseMetaFile(self, path): # Read the .meta file # it doesn't seem worth to apply caching here meta_fname = os.path.splitext(path)[0] + '.meta' meta_content = filetool.read(meta_fname) imgDict = json.loads(meta_content) # Loop through the images of the .meta file for imageId, imageSpec_ in imgDict.items(): # sort of like this: imageId : [width, height, type, combinedUri, off-x, off-y] imageObject = Image() imageObject.id = imageId imageObject = imageObject.fromMeta(imageSpec_) self.embeds.append(imageObject) return
def _scanResourcePath(self): resources = set() if self.resourcePath is None: return resources if not os.path.isdir(os.path.join(self.path, self.resourcePath)): self._console.info("Lib<%s>: Skipping non-existing resource path" % self.namespace) return resources path = os.path.join(self.path, self.resourcePath) self._console.debug("Scanning resource folder...") path = os.path.abspath(path) lib_prefix_len = len(path) if not path.endswith(os.sep): lib_prefix_len += 1 for root, dirs, files in filetool.walk(path): # filter ignored directories for dir in dirs: if self._ignoredDirEntries.match(dir): dirs.remove(dir) for file in files: if self._ignoredDirEntries.match(file): continue fpath = os.path.join(root, file) fpath = os.path.normpath(fpath) if Image.isImage(fpath): if CombinedImage.isCombinedImage(fpath): res = CombinedImage(fpath) else: res = Image(fpath) res.analyzeImage() elif FontMap.isFontMap(fpath): res = FontMap(fpath) else: res = Resource(fpath) res.set_id(Path.posifyPath(fpath[lib_prefix_len:])) res.library = self resources.add(res) self._console.indent() self._console.debug("Found %s resources" % len(resources)) self._console.outdent() return resources
def _scanResourcePath(self, path): if not os.path.exists(path): raise ValueError("The given resource path does not exist: %s" % path) self._console.debug("Scanning resource folder...") path = os.path.abspath(path) lib_prefix_len = len(path) if not path.endswith(os.sep): lib_prefix_len += 1 for root, dirs, files in filetool.walk(path): # filter ignored directories for dir in dirs: if self._ignoredDirectories.match(dir): dirs.remove(dir) for file in files: fpath = os.path.join(root, file) fpath = os.path.normpath(fpath) if Image.isImage(fpath): if CombinedImage.isCombinedImage(fpath): res = CombinedImage(fpath) else: res = Image(fpath) res.analyzeImage() else: res = Resource(fpath) res.id = Path.posifyPath(fpath[lib_prefix_len:]) res.library= self self.resources.add(res) return
class CombinedImage(Image): def __init__(self, path=None): super(CombinedImage, self).__init__(path) self.embeds = [] # embedded images if path: self.parseMetaFile(path) def parseMetaFile(self, path): # Read the .meta file # it doesn't seem worth to apply caching here meta_fname = os.path.splitext(path)[0]+'.meta' try: meta_content = filetool.read(meta_fname) imgDict = json.loads(meta_content) except Exception, e: msg = "Reading of .meta file failed: '%s'" % meta_fname + ( "\n%s" % e.args[0] if e.args else "" ) e.args = (msg,) + e.args[1:] raise # Loop through the images of the .meta file for imageId, imageSpec_ in imgDict.items(): # sort of like this: imageId : [width, height, type, combinedUri, off-x, off-y] imageObject = Image() imageObject.id = imageId imageObject = imageObject.fromMeta(imageSpec_) self.embeds.append(imageObject) return
def slice(self, source, dest_prefix, border, trim_width): source_file = source dest_file = os.path.join(os.path.dirname(source), dest_prefix) imginf = Image(source_file).getInfoMap() width, height = imginf['width'], imginf['height'] crop_cmd = "convert %s -crop %sx%s+%s+%s +repage %s" if isinstance(border, int): single_border = True elif not isinstance(border, list) or (isinstance(border, list) and not (len(border) == 4)): raise RuntimeError, "Border must be one integer or an array with four integers" else: single_border = False # split if single_border: os.system(crop_cmd % (source_file, border, border, 0, 0, dest_file + "-tl.png")) os.system(crop_cmd % (source_file, border, border, border, 0, dest_file + "-t.png")) os.system(crop_cmd % (source_file, border, border, width-border, 0, dest_file + "-tr.png")) os.system(crop_cmd % (source_file, border, height-2*border, 0, border, dest_file + "-l.png")) if trim_width: os.system(crop_cmd % (source_file, min(20, width-2*border), height-2*border, border, border, dest_file + "-c.png")) else: os.system(crop_cmd % (source_file, width-2*border, height-2*border, border, border, dest_file + "-c.png")) os.system(crop_cmd % (source_file, border, height-2*border, width-border, border, dest_file + "-r.png")) os.system(crop_cmd % (source_file, border, border, 0, height-border, dest_file + "-bl.png")) os.system(crop_cmd % (source_file, border, border, border, height-border, dest_file + "-b.png")) os.system(crop_cmd % (source_file, border, border, width-border, height-border, dest_file + "-br.png")) else: if border[0] > 0 and border[3] > 0: os.system(crop_cmd % (source_file, border[3], border[0], 0, 0, dest_file + "-tl.png")) if border[0] > 0: os.system(crop_cmd % (source_file, width - border[3] - border[1], border[0], border[3], 0, dest_file + "-t.png")) if border[0] > 0 and border[1] > 0: os.system(crop_cmd % (source_file, border[1], border[0], width - border[1], 0, dest_file + "-tr.png")) if border[3] > 0: os.system(crop_cmd % (source_file, border[3], height - border[0] - border[2], 0, border[0], dest_file + "-l.png")) if trim_width: os.system(crop_cmd % (source_file, min(20, width- border[3] - border[1]), height - border[0] - border[2], border[3], border[0], dest_file + "-c.png")) else: os.system(crop_cmd % (source_file, width- border[3] - border[1], height - border[0] - border[2], border[3], border[0], dest_file + "-c.png")) if border[1] > 0: os.system(crop_cmd % (source_file, border[1], height - border[0] - border[2], width - border[1], border[0], dest_file + "-r.png")) if border[2] > 0 and border[3] > 0: os.system(crop_cmd % (source_file, border[3], border[2], 0, height - border[2], dest_file + "-bl.png")) if border[2] > 0: os.system(crop_cmd % (source_file, width- border[3] - border[1], border[2], border[3], height - border[2], dest_file + "-b.png")) if border[2] > 0 and border[1] > 0: os.system(crop_cmd % (source_file, border[1], border[2], width - border[1], height - border[2], dest_file + "-br.png")) # for css3, the original images are used shutil.copyfile(source_file, dest_file + ".png")
def _scanResourcePath(self, path): if not os.path.exists(path): raise ValueError("The given resource path does not exist: %s" % path) self._console.debug("Scanning resource folder...") path = os.path.abspath(path) lib_prefix_len = len(path) if not path.endswith(os.sep): lib_prefix_len += 1 self.resources = set() for root, dirs, files in filetool.walk(path): # filter ignored directories for dir in dirs: if self._ignoredDirEntries.match(dir): dirs.remove(dir) for file in files: if self._ignoredDirEntries.match(file): continue fpath = os.path.join(root, file) fpath = os.path.normpath(fpath) if Image.isImage(fpath): if CombinedImage.isCombinedImage(fpath): res = CombinedImage(fpath) else: res = Image(fpath) res.analyzeImage() else: res = Resource(fpath) res.set_id(Path.posifyPath(fpath[lib_prefix_len:])) res.library = self self.resources.add(res) self._console.indent() self._console.debug("Found %s resources" % len(self.resources)) self._console.outdent() return
def combine(self, combined, files, horizontal, type="extension"): self._console.indent() if horizontal: orientation = "x1" else: orientation = "1x" # combine config = [] clips = [] top = 0 left = 0 allfiles = [] for file in files: allfiles.extend(glob.glob(file)) #self._console.debug("Combining the following images: %r" % allfiles) for file in allfiles: if not os.path.exists(file): self._console.warn("Non-existing file spec, skipping: %s" % file) continue clips.append(file) imginfo = Image(file).getInfoMap() width, height = imginfo['width'], imginfo['height'] config.append({ 'file': file, 'combined': combined, 'left': -left, 'top': -top, 'width': width, 'height': height, 'type': imginfo['type'] }) if horizontal: left += width else: top += height if len(clips) == 0: self._console.warn("No images to combine; skipping") else: filetool.directory(os.path.dirname(combined)) if type == "extension": self.combineImgMagick(clips, combined, orientation) elif type == "base64": self.combineBase64(config) self._console.outdent() return config
def _scanResourcePath(self): resources = set() if self.resourcePath is None: return resources if not os.path.isdir(os.path.join(self.path,self.resourcePath)): self._console.info("Lib<%s>: Skipping non-existing resource path" % self.namespace) return resources path = os.path.join(self.path,self.resourcePath) self._console.debug("Scanning resource folder...") path = os.path.abspath(path) lib_prefix_len = len(path) if not path.endswith(os.sep): lib_prefix_len += 1 for root, dirs, files in filetool.walk(path): # filter ignored directories for dir in dirs: if self._ignoredDirEntries.match(dir): dirs.remove(dir) for file in files: if self._ignoredDirEntries.match(file): continue fpath = os.path.join(root, file) fpath = os.path.normpath(fpath) if Image.isImage(fpath): if CombinedImage.isCombinedImage(fpath): res = CombinedImage(fpath) else: res = Image(fpath) res.analyzeImage() elif FontMap.isFontMap(fpath): res = FontMap(fpath) else: res = Resource(fpath) res.set_id(Path.posifyPath(fpath[lib_prefix_len:])) res.library= self resources.add(res) self._console.indent() self._console.debug("Found %s resources" % len(resources)) self._console.outdent() return resources
def runImageCombining(jobconf, confObj): def extractFromPrefixSpec(prefixSpec): prefix = altprefix = "" if not prefixSpec or not isinstance(prefixSpec, types.ListType): if jobconf.get("config-warnings/combine-images", True): console.warn("Missing or incorrect prefix spec, might lead to incorrect resource id's.") elif len(prefixSpec) == 2 : # prefixSpec = [ prefix, altprefix ] prefix, altprefix = prefixSpec elif len(prefixSpec) == 1: prefix = prefixSpec[0] altprefix = "" return prefix, altprefix ## # strip prefix - if available - from imagePath, and replace by altprefix def getImageId(imagePath, prefixSpec): prefix, altprefix = extractFromPrefixSpec(prefixSpec) imageId = imagePath # init _, imageId, _ = Path.getCommonPrefix(imagePath, prefix) # assume: imagePath = prefix "/" imageId if altprefix: imageId = altprefix + "/" + imageId imageId = Path.posifyPath(imageId) return imageId ## # create a dict with the clipped image file path as key, and prefix elements as value def getClippedImagesDict(imageSpec): imgDict = {} inputStruct = imageSpec['input'] for group in inputStruct: prefixSpec = group.get('prefix', []) prefix, altprefix = extractFromPrefixSpec(prefixSpec) if prefix: prefix = confObj.absPath(prefix) for filepatt in group['files']: num_files = 0 for file in glob.glob(confObj.absPath(filepatt)): # resolve file globs - TODO: can be removed in generator.action.ImageClipping console.debug("adding image %s" % file) imgDict[file] = [prefix, altprefix] num_files += 1 if num_files == 0: raise ValueError("Non-existing file spec: %s" % filepatt) return imgDict # ---------------------------------------------------------------------- if not jobconf.get("combine-images", False): return console = Context.console cache = Context.cache console.info("Combining images...") console.indent() imageClipper = ImageClipping(console, cache, jobconf) images = jobconf.get("combine-images/images", {}) for image, imgspec in images.iteritems(): console.info("Creating image %s" % image) console.indent() imageId= getImageId(image, imgspec.get('prefix', [])) image = confObj.absPath(image) # abs output path config = {} # create a dict of clipped image objects - for later look-up clippedImages = getClippedImagesDict(imgspec) # collect list of all input files, no matter where they come from input = sorted(clippedImages.keys()) # collect layout property if 'layout' in imgspec: layout = imgspec['layout'] == "horizontal" else: layout = "horizontal" == "horizontal" # default horizontal=True # get type of combined image (png, base64, ...) combtype = "base64" if image.endswith(".b64.json") else "extension" # create the combined image subconfigs = imageClipper.combine(image, input, layout, combtype) # for the meta information, go through the list of returned subconfigs (one per clipped image) for sub in subconfigs: x = Image() x.combId, x.left, x.top, x.width, x.height, x.format = ( imageId, sub['left'], sub['top'], sub['width'], sub['height'], sub['type']) subId = getImageId(sub['file'], clippedImages[sub['file']]) config[subId] = x.toMeta() # store meta data for this combined image bname = os.path.basename(image) ri = bname.rfind('.') if ri > -1: bname = bname[:ri] bname += '.meta' meta_fname = os.path.join(os.path.dirname(image), bname) console.debug("writing meta file %s" % meta_fname) filetool.save(meta_fname, json.dumps(config, ensure_ascii=False, sort_keys=True)) console.outdent() # handle base64 type, need to write "combined image" to file if combtype == "base64": combinedMap = {} for sub in subconfigs: subMap = {} subId = getImageId(sub['file'], clippedImages[sub['file']]) subMap['width'] = sub['width'] subMap['height'] = sub['height'] subMap['type'] = sub['type'] subMap['encoding'] = sub['encoding'] subMap['data'] = sub['data'] combinedMap[subId] = subMap filetool.save(image, json.dumpsCode(combinedMap)) console.outdent() return
def slice(self, source, dest_prefix, border, trim_width): #convert_cmd = "convert %s -crop %sx%s+%s+%s +repage %s" #convert_cmd = "convert %(infile)s -crop %(xoff)sx%(yoff)s+%(xorig)s+%(yorig)s +repage %(outfile)s" convert_cmd = self._job.get("slice-images/convert-cmd", "") if not convert_cmd: raise ConfigurationError( "You need to specify a command template for the \"convert\" command (in slice-images/convert-cmd)" ) source_file = source dest_file = os.path.join(os.path.dirname(source), dest_prefix) imginf = Image(source_file).getInfoMap() width, height = imginf['width'], imginf['height'] if isinstance(border, int): single_border = True elif not isinstance(border, list) or (isinstance(border, list) and not (len(border) == 4)): raise RuntimeError, "Border must be one integer or an array with four integers" else: single_border = False # Split borders and corners from source image # Single width for all borders if single_border: # top-left corner #os.system(convert_cmd % (source_file, border, border, 0, 0, dest_file + "-tl.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-tl.png", 'xoff': border, 'yoff': border, 'xorig': 0, 'yorig': 0, }) # top border #os.system(convert_cmd % (source_file, border, border, border, 0, dest_file + "-t.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-t.png", 'xoff': border, 'yoff': border, 'xorig': border, 'yorig': 0, }) # top-right corner #os.system(convert_cmd % (source_file, border, border, width-border, 0, dest_file + "-tr.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-tr.png", 'xoff': border, 'yoff': border, 'xorig': width - border, 'yorig': 0, }) # left border #os.system(convert_cmd % (source_file, border, height-2*border, 0, border, dest_file + "-l.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-l.png", 'xoff': border, 'yoff': height - 2 * border, 'xorig': 0, 'yorig': border, }) # center piece if trim_width: #os.system(convert_cmd % (source_file, min(20, width-2*border), height-2*border, border, border, dest_file + "-c.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-c.png", 'xoff': min(20, width - 2 * border), 'yoff': height - 2 * border, 'xorig': border, 'yorig': border, }) else: #os.system(convert_cmd % (source_file, width-2*border, height-2*border, border, border, dest_file + "-c.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-c.png", 'xoff': width - 2 * border, 'yoff': height - 2 * border, 'xorig': border, 'yorig': border, }) # right border #os.system(convert_cmd % (source_file, border, height-2*border, width-border, border, dest_file + "-r.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-r.png", 'xoff': border, 'yoff': height - 2 * border, 'xorig': width - border, 'yorig': border, }) # bottom-left corner #os.system(convert_cmd % (source_file, border, border, 0, height-border, dest_file + "-bl.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-bl.png", 'xoff': border, 'yoff': border, 'xorig': 0, 'yorig': height - border, }) # bottom border #os.system(convert_cmd % (source_file, border, border, border, height-border, dest_file + "-b.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-b.png", 'xoff': border, 'yoff': border, 'xorig': border, 'yorig': height - border, }) # bottom-right corner #os.system(convert_cmd % (source_file, border, border, width-border, height-border, dest_file + "-br.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-br.png", 'xoff': border, 'yoff': border, 'xorig': width - border, 'yorig': height - border, }) # Individual borders else: if border[0] > 0 and border[3] > 0: # top-left corner #os.system(convert_cmd % (source_file, border[3], border[0], 0, 0, dest_file + "-tl.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-tl.png", 'xoff': border[3], 'yoff': border[0], 'xorig': 0, 'yorig': 0, }) if border[0] > 0: # top border #os.system(convert_cmd % (source_file, width - border[3] - border[1], border[0], border[3], 0, dest_file + "-t.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-t.png", 'xoff': width - border[3] - border[1], 'yoff': border[0], 'xorig': border[3], 'yorig': 0, }) if border[0] > 0 and border[1] > 0: # top-right corner #os.system(convert_cmd % (source_file, border[1], border[0], width - border[1], 0, dest_file + "-tr.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-tr.png", 'xoff': border[1], 'yoff': border[0], 'xorig': width - border[1], 'yorig': 0, }) if border[3] > 0: # left border #os.system(convert_cmd % (source_file, border[3], height - border[0] - border[2], 0, border[0], dest_file + "-l.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-l.png", 'xoff': border[3], 'yoff': height - border[0] - border[2], 'xorig': 0, 'yorig': border[0], }) # center piece if trim_width: #os.system(convert_cmd % (source_file, min(20, width- border[3] - border[1]), height - border[0] - border[2], border[3], border[0], dest_file + "-c.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-c.png", 'xoff': min(20, width - border[3] - border[1]), 'yoff': height - border[0] - border[2], 'xorig': border[3], 'yorig': border[0], }) else: #os.system(convert_cmd % (source_file, width- border[3] - border[1], height - border[0] - border[2], border[3], border[0], dest_file + "-c.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-c.png", 'xoff': width - border[3] - border[1], 'yoff': height - border[0] - border[2], 'xorig': border[3], 'yorig': border[0], }) if border[1] > 0: # right border #os.system(convert_cmd % (source_file, border[1], height - border[0] - border[2], width - border[1], border[0], dest_file + "-r.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-r.png", 'xoff': border[1], 'yoff': height - border[0] - border[2], 'xorig': width - border[1], 'yorig': border[0], }) if border[2] > 0 and border[3] > 0: # bottom-left corner #os.system(convert_cmd % (source_file, border[3], border[2], 0, height - border[2], dest_file + "-bl.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-bl.png", 'xoff': border[3], 'yoff': border[2], 'xorig': 0, 'yorig': height - border[2], }) if border[2] > 0: # bottom border #os.system(convert_cmd % (source_file, width- border[3] - border[1], border[2], border[3], height - border[2], dest_file + "-b.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-b.png", 'xoff': width - border[3] - border[1], 'yoff': border[2], 'xorig': border[3], 'yorig': height - border[2], }) if border[2] > 0 and border[1] > 0: # bottom-right corner #os.system(convert_cmd % (source_file, border[1], border[2], width - border[1], height - border[2], dest_file + "-br.png")) os.system( convert_cmd % { 'infile': source_file, 'outfile': dest_file + "-br.png", 'xoff': border[1], 'yoff': border[2], 'xorig': width - border[1], 'yorig': height - border[2], }) # for css3, the original images are used shutil.copyfile(source_file, dest_file + ".png")
def combineBase64(self, imgInfos): for imgInfo in imgInfos: base64dat = Image(imgInfo['file']).toBase64() imgInfo['encoding'] = "base64" imgInfo['data'] = base64dat