mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 18:25:10 +00:00
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>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -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")"
|
||||
local folder="$1"
|
||||
local param="$2"
|
||||
shift
|
||||
shift
|
||||
|
||||
# Always output as .bmp
|
||||
output="${output%.*}.bmp"
|
||||
mkdir -p "$folder"
|
||||
# convert_to_bmp3.py takes '--scale' while ImageMagic takes '-scale'.
|
||||
[ -n "$param" ] && param="-$param"
|
||||
|
||||
# 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
|
||||
|
||||
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')"
|
||||
$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.
|
||||
|
||||
85
scripts/newbitmaps/images/convert_to_bmp3.py
Executable file
85
scripts/newbitmaps/images/convert_to_bmp3.py
Executable file
@@ -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)
|
||||
Reference in New Issue
Block a user