def processCombinedImg(data, meta_fname, combinedImageUri, combinedImageShortUri, combinedImageObject): # make sure lib and type info for the combined image are present assert combinedImageObject.lib, combinedImageObject.type # see if we have cached the contents (json) of this .meta file cacheId = "imgcomb-%s" % meta_fname imgDict = self._cache.read(cacheId, meta_fname) if imgDict == None: mfile = open(meta_fname) imgDict = simplejson.loads(mfile.read()) mfile.close() self._cache.write(cacheId, imgDict) # now loop through the dict structure from the .meta file for imagePath, imageSpec_ in imgDict.items(): # sort of like this: imagePath : [width, height, type, combinedUri, off-x, off-y] imageObject = ImgInfoFmt(imageSpec_) # turn this into an ImgInfoFmt object, to abstract from representation in .meta file and loader script # have to normalize the uri's from the meta file #imageUri = normalizeImgUri(imagePath, combinedImageUri, imageObject.mappedId) imageUri = imagePath ## replace lib uri with lib namespace in imageUri imageShortUri = extractAssetPart(librespath, imageUri) imageShortUri = Path.posifyPath(imageShortUri) # now put all elements of the image object together imageObject.mappedId = combinedImageShortUri # correct the mapped uri of the combined image imageObject.lib = combinedImageObject.lib imageObject.mtype = combinedImageObject.type imageObject.mlib = combinedImageObject.lib # and store it in the data structure data[imageShortUri] = imageObject.flatten() # this information takes precedence over existing return
def generateResourceInfoCode(self, settings, libs, format=False): """Pre-calculate image information (e.g. sizes)""" data = {} resdata = data imgpatt = re.compile(r'\.(png|jpeg|jpg|gif)$', re.I) skippatt = re.compile(r'\.(meta|py)$', re.I) self._console.info("Analysing assets...") self._console.indent() self._imageInfo = ImageInfo(self._console, self._cache) # some helper functions def replaceWithNamespace(imguri, liburi, libns): pre,libsfx,imgsfx = Path.getCommonPrefix(liburi, imguri) if imgsfx[0] == os.sep: imgsfx = imgsfx[1:] # strip leading '/' imgshorturi = os.path.join("${%s}" % libns, imgsfx) return imgshorturi def extractAssetPart(libresuri, imguri): pre,libsfx,imgsfx = Path.getCommonPrefix(libresuri, imguri) # split libresuri from imguri if imgsfx[0] == os.sep: imgsfx = imgsfx[1:] # strip leading '/' return imgsfx # use the bare img suffix as its asset Id ## # calculate the uri of the clipped image, by taking the uri of the combined image, # "substracting" its asset id (the right end), taking what remains (the left # part), extracting the asset id of the clipped image, and pre-fixing it with the # left part of the combined image uri. # imageUri = (combinedUri - combinedAssetId) + imageAssetId # # @param uriFromMetafile |String| the path of the clipped image from when the meta file was generated, # like: "./source/resource/qx/decoration/Modern/..." # @param trueCombinedUri |String| the uri of the combined image, as returned from # the library scan and adapted for the current # application, like: # "../../framework/source/resource/qx/decoration/Modern/panel-combined.png" # @param combinedUriFromMetafile |String| the path of the combined image, as # recorded in the .meta file def normalizeImgUri(uriFromMetafile, trueCombinedUri, combinedUriFromMetafile): # normalize paths (esp. "./x" -> "x") (uriFromMetafile, trueCombinedUri, combinedUriFromMetafile) = map(os.path.normpath, (uriFromMetafile, trueCombinedUri, combinedUriFromMetafile)) # get the "wrong" left part of the combined image, as used in the .meta file (in mappedUriPrefix) trueUriPrefix, mappedUriPrefix, _ = Path.getCommonSuffix(trueCombinedUri, combinedUriFromMetafile) # ...and strip it from clipped image, to get a correct image id (in uriSuffix) _, _, uriSuffix = Path.getCommonPrefix(mappedUriPrefix, uriFromMetafile) # ...then compose the correct prefix with the correct suffix normalUri = os.path.normpath(os.path.join(trueUriPrefix, uriSuffix)) return normalUri ## # - reads through the entries of a .meta file, which is the contents of a combined image # - for each contained image: # - computes the image id ("short uri") # - collects the list of interesting values (width, height, ..., combined image, ...) # - and adds these as key:value to the general data map of images # # @param data |{imageId:[width, height, ...]}| general map for qx.$$resource in loader # @param meta_fname |String| file path of the .meta file # @param combinedImageUri |String| uri of the combined image # @param combinedImageShortUri |String| short uri (image/asset id) of the combined image # these are necessary to compute the image id's of the contained imgs # @param combinedImageObject |ImgInfoFmt| an ImgInfoFmt wrapper object for the combined image # (interesting for the lib and type info) def processCombinedImg(data, meta_fname, combinedImageUri, combinedImageShortUri, combinedImageObject): # make sure lib and type info for the combined image are present assert combinedImageObject.lib, combinedImageObject.type # see if we have cached the contents (json) of this .meta file cacheId = "imgcomb-%s" % meta_fname imgDict = self._cache.read(cacheId, meta_fname) if imgDict == None: mfile = open(meta_fname) imgDict = simplejson.loads(mfile.read()) mfile.close() self._cache.write(cacheId, imgDict) # now loop through the dict structure from the .meta file for imagePath, imageSpec_ in imgDict.items(): # sort of like this: imagePath : [width, height, type, combinedUri, off-x, off-y] imageObject = ImgInfoFmt(imageSpec_) # turn this into an ImgInfoFmt object, to abstract from representation in .meta file and loader script # have to normalize the uri's from the meta file #imageUri = normalizeImgUri(imagePath, combinedImageUri, imageObject.mappedId) imageUri = imagePath ## replace lib uri with lib namespace in imageUri imageShortUri = extractAssetPart(librespath, imageUri) imageShortUri = Path.posifyPath(imageShortUri) # now put all elements of the image object together imageObject.mappedId = combinedImageShortUri # correct the mapped uri of the combined image imageObject.lib = combinedImageObject.lib imageObject.mtype = combinedImageObject.type imageObject.mlib = combinedImageObject.lib # and store it in the data structure data[imageShortUri] = imageObject.flatten() # this information takes precedence over existing return # -- main -------------------------------------------------------------- resourceFilter= self._resourceHandler.getResourceFilterByAssets(self._classList) for lib in libs: #libresuri = self._computeResourceUri(lib, "", rType='resource', appRoot=self.approot) librespath = os.path.normpath(os.path.join(lib['path'], lib['resource'])) resourceList = self._resourceHandler.findAllResources([lib], resourceFilter) # resourceList = [[file1,uri1],[file2,uri2],...] for resource in resourceList: ##assetId = replaceWithNamespace(imguri, libresuri, lib['namespace']) #assetId = extractAssetPart(libresuri, resource[1]) assetId = extractAssetPart(librespath,resource) assetId = Path.posifyPath(assetId) if imgpatt.search(resource): # handle images imgpath= resource #imguri = resource[1] imguri = resource imageInfo = self._imageInfo.getImageInfo(imgpath, assetId) # use an ImgInfoFmt object, to abstract from flat format imgfmt = ImgInfoFmt() imgfmt.lib = lib['namespace'] if not 'type' in imageInfo: raise RuntimeError, "Unable to get image info from file: %s" % imgpath imgfmt.type = imageInfo['type'] # check for a combined image and process the contained images meta_fname = os.path.splitext(imgpath)[0]+'.meta' if os.path.exists(meta_fname): # add included imgs processCombinedImg(data, meta_fname, imguri, assetId, imgfmt) # add this image directly # imageInfo = {width, height, filetype} if not 'width' in imageInfo or not 'height' in imageInfo: raise RuntimeError, "Unable to get image info from file: %s" % imgpath imgfmt.width, imgfmt.height, imgfmt.type = ( imageInfo['width'], imageInfo['height'], imageInfo['type']) # check if img is already registered as part of a combined image if assetId in data: x = ImgInfoFmt() x.fromFlat(data[assetId]) if x.mappedId: continue # don't overwrite the combined entry data[assetId] = imgfmt.flatten() elif skippatt.search(resource[0]): continue else: # handle other resources resdata[assetId] = lib['namespace'] # wpbasti: Image data is not part relevant yet. self._console.outdent() return resdata