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) |