diff options
author | Hung-Te Lin <hungte@chromium.org> | 2012-11-02 17:49:22 +0800 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-11-05 16:52:50 -0800 |
commit | 3f9857420f9fea0a27a3190cf0079a200460921d (patch) | |
tree | 141f6e8bea40c2fce95a34abf8b80d1720e0fd42 | |
parent | 7909cb8293582fafe7dbf4f463ec95a5567a58c8 (diff) | |
download | vboot-3f9857420f9fea0a27a3190cf0079a200460921d.tar.gz |
newbitmaps: Speed up image conversion by using PIL.
Running ImageMagick + PIL is a redundant task; we should let PIL
do flatten, resize, and exporting to different format.
Before: real 11m54s, user 37m10s.
After: real 8m3s, user 16m33s.
BRANCH=none
BUG=none
TEST=make
Change-Id: I65f1e5b769161650310abca46851824755402d9b
Reviewed-on: https://gerrit.chromium.org/gerrit/37200
Tested-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Ready: Hung-Te Lin <hungte@chromium.org>
-rw-r--r-- | scripts/newbitmaps/images/assets/BadSD.png | bin | 2114 -> 2819 bytes | |||
-rw-r--r-- | scripts/newbitmaps/images/assets/BadUSB.png | bin | 2842 -> 3640 bytes | |||
-rwxr-xr-x | scripts/newbitmaps/images/build_images | 67 | ||||
-rwxr-xr-x | scripts/newbitmaps/images/convert_to_bmp3.py | 85 |
4 files changed, 100 insertions, 52 deletions
diff --git a/scripts/newbitmaps/images/assets/BadSD.png b/scripts/newbitmaps/images/assets/BadSD.png Binary files differindex 0dd0e660..6e903570 100644 --- a/scripts/newbitmaps/images/assets/BadSD.png +++ b/scripts/newbitmaps/images/assets/BadSD.png diff --git a/scripts/newbitmaps/images/assets/BadUSB.png b/scripts/newbitmaps/images/assets/BadUSB.png Binary files differindex 82d0728b..aa21a450 100644 --- a/scripts/newbitmaps/images/assets/BadUSB.png +++ b/scripts/newbitmaps/images/assets/BadUSB.png diff --git a/scripts/newbitmaps/images/build_images b/scripts/newbitmaps/images/build_images index 72147a42..35f2c813 100755 --- a/scripts/newbitmaps/images/build_images +++ b/scripts/newbitmaps/images/build_images @@ -14,54 +14,23 @@ BACKGROUND_IMAGE=Background_white.png # Output file name. BMPBLK_OUTPUT="bmpblock.bin" +SCRIPT_BASE="$(dirname $(readlink -f "$0"))" + die() { echo "ERROR: $*" >&2 exit 1 } convert_to_bmp3() { - local input="$1" - local folder="$2" - local param="$3" - local output="$(basename "$input")" - - # Always output as .bmp - output="${output%.*}.bmp" - mkdir -p "$folder" - - # TODO(hungte) Use PIL to replace ImageMagic. - - # When input has Alpha channel, we need to fill the background properly - # otherwise ImageMagick will fill it with black. The operation (-flatten) is - # so slow so we only want to do that if the input source really has - # transparency. - if [ "$#" -gt 3 ]; then - flatten="$4" - else - # Auto-detect - if [ "$(identify -format "%A" "$input")" = "True" ]; then - flatten="-background $BACKGROUND_COLOR -flatten" - else - flatten="" - fi - fi + local folder="$1" + local param="$2" + shift + shift - echo "$input -> $folder/$output $flatten" - convert "$input" $flatten \ - -compress none -alpha off -colors 256 \ - $param "BMP3:$folder/$output" - - # ImageMagic quantization may choose arbitrary color depth, even if we assign - # -depth or -colors; so a single-color background may become 1 bit per pixel - # after convertion. To workaround that, we use Python Image Library which - # always generates 8bpp BMP file. - # TODO(hungte) Find a better way to decide if PIL is required. Unfortunately, - # ImageMagic identify "%z" is not always what we're looking for... - local fn="$folder/$output" - # Converting from '1' to 'P' may be not supported by PIL, so converting to - # 'RGB' mode first is required. - local param="convert('RGB').convert('P', dither=None, palette=Image.ADAPTIVE)" - python -c "import Image;Image.open('$fn').$param.save('$fn')" + # convert_to_bmp3.py takes '--scale' while ImageMagic takes '-scale'. + [ -n "$param" ] && param="-$param" + + $SCRIPT_BASE/convert_to_bmp3.py $param --outdir "$folder" "$@" } main() { @@ -163,9 +132,9 @@ main() { # Url.bmp by <span foreground="blue">http://</span>. for X in *.png assets/*.png; do if [ "$X" = "$BACKGROUND_IMAGE" ]; then - convert_to_bmp3 "$X" "$output" "$background_scale_param" + convert_to_bmp3 "$output" "$background_scale_param" "$X" else - convert_to_bmp3 "$X" "$output" "$scale_param" + convert_to_bmp3 "$output" "$scale_param" "$X" fi done @@ -174,9 +143,7 @@ main() { # speed up. echo "Preparing common strings..." base="../strings" - for X in $base/*.png; do - convert_to_bmp3 "$X" "$output" "$scale_param" "" - done + convert_to_bmp3 "$output" "$scale_param" $base/*.png echo "Preparing localized messages... $LOCALES" base="../strings/localized_text" @@ -191,9 +158,7 @@ main() { fi for locale in $LOCALES; do # Prepare all locales. - for X in $base/$locale/*.png; do - convert_to_bmp3 "$X" "$output/locale/$locale" "$scale_param" "" - done + convert_to_bmp3 "$output/locale/$locale" "$scale_param" $base/$locale/*.png done if [ -n "$replace_files" ]; then @@ -210,9 +175,7 @@ main() { echo "Preparing fonts..." base="../strings/font" - for X in $base/*.png; do - convert_to_bmp3 "$X" "$output/font" "$scale_param" "" - done + convert_to_bmp3 "$output/font" "$scale_param" $base/*.png bmpblk_font --outfile "$output/hwid_fonts.bin" "$output"/font/*.bmp # Create YAML file. diff --git a/scripts/newbitmaps/images/convert_to_bmp3.py b/scripts/newbitmaps/images/convert_to_bmp3.py new file mode 100755 index 00000000..f5afd33d --- /dev/null +++ b/scripts/newbitmaps/images/convert_to_bmp3.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import getopt +import os +import re +import sys + +import Image + + +BACKGROUND_COLOR = (255, 255, 255) +DEFAULT_OUTPUT_EXT = '.bmp' + + +def parse_scale_factor(pattern, original_size): + # Format: w%xh%, or wxh! + factor = re.findall(r'^([0-9]+)%x([0-9]+)%$', pattern) + if factor: + w, h = factor[0] + return (int(int(w) / 100.0 * original_size[0]), + int(int(h) / 100.0 * original_size[1])) + + factor = re.findall(r'^([0-9]+)x([0-9]+)!?$', pattern) + if factor: + return map(int, factor[0]) + + raise Exception('Unknown scaling parameter: %s', pattern) + + +def convert_to_bmp(input_file, scale, outdir, background=BACKGROUND_COLOR): + source = Image.open(input_file) + output_file = os.path.join( + outdir, + os.path.basename(input_file).rpartition('.')[0] + DEFAULT_OUTPUT_EXT) + + # Process alpha channel and transparency. + if source.mode == 'RGBA': + target = Image.new('RGB', source.size, background) + source.load() # required for source.split() + mask = source.split()[-1] + target.paste(source, mask=mask) + elif (source.mode == 'P') and ('transparency' in source.info): + exit('Sorry, PNG with RGBA palette is not supported.') + elif source.mode != 'RGB': + target = source.convert('RGB') + else: + target = source + + # Process scaling + if scale: + new_size = parse_scale_factor(scale, source.size) + target = target.resize(new_size, Image.BICUBIC) + + # Export and downsample color space. + target.convert('P', dither=None, palette=Image.ADAPTIVE).save(output_file) + + +def main(argv): + scale_param = '' + outdir = '' + try: + opts, args = getopt.getopt(argv[1:], '', ('scale=', 'outdir=')) + for key, value in opts: + if key == '--scale': + scale_param = value + elif key == '--outdir': + outdir = value + if len(args) < 1: + raise Exception('need more param') + except: + exit('Usage: ' + argv[0] + + ' [--scale WxH!|--scale W%xH%] [--outdir DIR] files(s)...') + + if outdir and not os.path.isdir(outdir): + os.makedirs(outdir) + + for source_file in args: + convert_to_bmp(source_file, scale_param, outdir) + + +if __name__ == '__main__': + main(sys.argv) |