mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-25 02:35:22 +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.
|
# Output file name.
|
||||||
BMPBLK_OUTPUT="bmpblock.bin"
|
BMPBLK_OUTPUT="bmpblock.bin"
|
||||||
|
|
||||||
|
SCRIPT_BASE="$(dirname $(readlink -f "$0"))"
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
echo "ERROR: $*" >&2
|
echo "ERROR: $*" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_to_bmp3() {
|
convert_to_bmp3() {
|
||||||
local input="$1"
|
local folder="$1"
|
||||||
local folder="$2"
|
local param="$2"
|
||||||
local param="$3"
|
shift
|
||||||
local output="$(basename "$input")"
|
shift
|
||||||
|
|
||||||
# Always output as .bmp
|
# convert_to_bmp3.py takes '--scale' while ImageMagic takes '-scale'.
|
||||||
output="${output%.*}.bmp"
|
[ -n "$param" ] && param="-$param"
|
||||||
mkdir -p "$folder"
|
|
||||||
|
|
||||||
# TODO(hungte) Use PIL to replace ImageMagic.
|
$SCRIPT_BASE/convert_to_bmp3.py $param --outdir "$folder" "$@"
|
||||||
|
|
||||||
# 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')"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
@@ -163,9 +132,9 @@ main() {
|
|||||||
# Url.bmp by <span foreground="blue">http://</span>.
|
# Url.bmp by <span foreground="blue">http://</span>.
|
||||||
for X in *.png assets/*.png; do
|
for X in *.png assets/*.png; do
|
||||||
if [ "$X" = "$BACKGROUND_IMAGE" ]; then
|
if [ "$X" = "$BACKGROUND_IMAGE" ]; then
|
||||||
convert_to_bmp3 "$X" "$output" "$background_scale_param"
|
convert_to_bmp3 "$output" "$background_scale_param" "$X"
|
||||||
else
|
else
|
||||||
convert_to_bmp3 "$X" "$output" "$scale_param"
|
convert_to_bmp3 "$output" "$scale_param" "$X"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -174,9 +143,7 @@ main() {
|
|||||||
# speed up.
|
# speed up.
|
||||||
echo "Preparing common strings..."
|
echo "Preparing common strings..."
|
||||||
base="../strings"
|
base="../strings"
|
||||||
for X in $base/*.png; do
|
convert_to_bmp3 "$output" "$scale_param" $base/*.png
|
||||||
convert_to_bmp3 "$X" "$output" "$scale_param" ""
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Preparing localized messages... $LOCALES"
|
echo "Preparing localized messages... $LOCALES"
|
||||||
base="../strings/localized_text"
|
base="../strings/localized_text"
|
||||||
@@ -191,9 +158,7 @@ main() {
|
|||||||
fi
|
fi
|
||||||
for locale in $LOCALES; do
|
for locale in $LOCALES; do
|
||||||
# Prepare all locales.
|
# Prepare all locales.
|
||||||
for X in $base/$locale/*.png; do
|
convert_to_bmp3 "$output/locale/$locale" "$scale_param" $base/$locale/*.png
|
||||||
convert_to_bmp3 "$X" "$output/locale/$locale" "$scale_param" ""
|
|
||||||
done
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -n "$replace_files" ]; then
|
if [ -n "$replace_files" ]; then
|
||||||
@@ -210,9 +175,7 @@ main() {
|
|||||||
|
|
||||||
echo "Preparing fonts..."
|
echo "Preparing fonts..."
|
||||||
base="../strings/font"
|
base="../strings/font"
|
||||||
for X in $base/*.png; do
|
convert_to_bmp3 "$output/font" "$scale_param" $base/*.png
|
||||||
convert_to_bmp3 "$X" "$output/font" "$scale_param" ""
|
|
||||||
done
|
|
||||||
bmpblk_font --outfile "$output/hwid_fonts.bin" "$output"/font/*.bmp
|
bmpblk_font --outfile "$output/hwid_fonts.bin" "$output"/font/*.bmp
|
||||||
|
|
||||||
# Create YAML file.
|
# 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