| Index: packagerChrome.py |
| =================================================================== |
| --- a/packagerChrome.py |
| +++ b/packagerChrome.py |
| @@ -18,6 +18,9 @@ |
| import sys, os, re, json, struct |
| from StringIO import StringIO |
| +import PIL.Image |
| +import PIL.ImageMath |
| + |
| import packager |
| from packager import readMetadata, getMetadataPath, getDefaultFileName, getBuildVersion, getTemplate, Files |
| @@ -279,10 +282,11 @@ |
| files[operaFile] = files[chromeFile] |
| del files[chromeFile] |
| - # Hack: Replace "Chrome" by "Opera" in the locales |
| + if params['type'] in ('opera', 'safari'): |
| + # Hack: Replace "Chrome" by "Opera" or "Safari" in the locales |
| for path, data in files.iteritems(): |
| if path.startswith("_locales/") and path.endswith("/messages.json"): |
| - files[path] = re.sub(r"\bChrome\b", "Opera", data) |
| + files[path] = re.sub(r"\bChrome\b", params['type'].capitalize(), data) |
| def signBinary(zipdata, keyFile): |
| import M2Crypto |
| @@ -308,6 +312,126 @@ |
| file.write(signature) |
| file.write(zipdata) |
| +class ImageConverter(object): |
| + def convert(self, params, files): |
| + for filename, chain in params['metadata'].items('convert_img'): |
| + steps = re.split(r'\s*->\s*', chain) |
| + image = PIL.Image.open(steps.pop(0)) |
| + |
| + for step in steps: |
| + filter, args = re.match(r'([^(]+)(?:\((.*)\))?', step).groups() |
| + args = tuple(re.split(r'\s*,\s*', args)) if args else () |
| + image = getattr(self, 'filter_' + filter)(image, *args) |
| + |
| + f = StringIO() |
| + f.name = filename |
| + image.save(f) |
| + files[filename] = f.getvalue() |
| + |
| + def filter_blend(self, image, *args): |
| + if len(args) == 2: # args = (filename, opacity) |
| + overlay = PIL.Image.open(args[0]) |
| + |
| + if image.mode != overlay.mode or image.mode == 'P': |
| + overlay = overlay.convert('RGBA') |
| + image = image.convert('RGBA') |
| + elif len(args) == 4: # args = (red, green, blue, opacity) |
| + overlay = PIL.Image.new('RGB', image.size, tuple(map(int, args[:3]))) |
| + |
| + if image.mode == 'P': |
| + image = image.convert('RGBA') |
| + |
| + if image.mode in ('RGBA', 'LA'): |
| + overlay = PIL.Image.merge('RGBA', overlay.split() + image.split()[-1:]) |
| + |
| + if image.mode != overlay.mode: |
| + image = image.convert(overlay.mode) |
| + else: |
| + raise TypeError |
| + |
| + return PIL.Image.blend(image, overlay, float(args[-1])) |
| + |
| + def filter_grayscale(self, image): |
| + if image.mode == 'P': |
| + image = image.convert('RGBA') |
| + |
| + bands = list(image.split()) |
| + alpha = bands.pop(-1) if image.mode in ('RGBA', 'LA') else None |
| + |
| + if len(bands) == 1: |
| + return image |
| + |
| + new_image = PIL.ImageMath.eval( |
| + "convert((%s) / %d, 'L')" % ( |
| + ' + '.join('image%d' % i for i in xrange(len(bands))), |
| + len(bands) |
| + ), |
| + **dict(('image%d' % i, band) for i, band in enumerate(bands)) |
| + ) |
| + |
| + if alpha: |
| + new_image = PIL.Image.merge('LA', [new_image, alpha]) |
| + |
| + return new_image |
| + |
| + def filter_colorToAlpha(self, image, *color): |
| + bands = [band.convert('F') for band in image.convert('RGBA').split()] |
| + color = map(float, color) |
| + |
| + # Find the maximum difference rate between source and color. I had to use two |
| + # difference functions because ImageMath.eval only evaluates the expression |
| + # once. |
| + alpha = PIL.ImageMath.eval('''\ |
| + float( |
| + max( |
| + max( |
| + max( |
| + difference1(red_band, cred_band), |
| + difference1(green_band, cgreen_band) |
| + ), |
| + difference1(blue_band, cblue_band) |
| + ), |
| + max( |
| + max( |
| + difference2(red_band, cred_band), |
| + difference2(green_band, cgreen_band) |
| + ), |
| + difference2(blue_band, cblue_band) |
| + ) |
| + ) |
| + )''', |
| + difference1=lambda source, col: (source - col) / (255.0 - col), |
| + difference2=lambda source, col: (col - source) / col, |
| + |
| + red_band = bands[0], |
| + green_band= bands[1], |
| + blue_band = bands[2], |
| + |
| + cred_band = color[0], |
| + cgreen_band= color[1], |
| + cblue_band = color[2], |
| + ) |
| + |
| + # Calculate the new image colors after the removal of the selected color |
| + new_bands = [ |
| + PIL.ImageMath.eval( |
| + "convert((image - color) / alpha + color, 'L')", |
| + image=band, |
| + color=col, |
| + alpha=alpha |
| + ) |
| + for band, col in zip(bands, color) |
| + ] |
| + |
| + # Add the new alpha band |
| + new_bands.append(PIL.ImageMath.eval( |
| + "convert(alpha_band * alpha, 'L')", |
| + alpha = alpha, |
| + alpha_band = bands[3] |
| + )) |
| + |
| + return PIL.Image.merge('RGBA', new_bands) |
| + |
| def createBuild(baseDir, type='chrome', outFile=None, buildNum=None, releaseBuild=False, keyFile=None, experimentalAPI=False, devenv=False): |
| metadata = readMetadata(baseDir, type) |
| version = getBuildVersion(baseDir, metadata, releaseBuild, buildNum) |
| @@ -335,6 +459,9 @@ |
| if metadata.has_section('convert_js'): |
| convertJS(params, files) |
| + if metadata.has_section('convert_img'): |
| + ImageConverter().convert(params, files) |
| + |
| if metadata.has_section('import_locales'): |
| importGeckoLocales(params, files) |