1#!/usr/bin/env python2 2# Copyright 2014 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6from __future__ import absolute_import 7from __future__ import division 8from __future__ import print_function 9 10import argparse 11import errno 12import logging 13import os 14import re 15import sys 16 17import common # pylint: disable=unused-import 18 19from autotest_lib.client.common_lib import utils 20from six.moves import range 21 22 23class ImageGeneratorError(Exception): 24 """Error in ImageGenerator.""" 25 pass 26 27 28class ImageGenerator(object): 29 """A class to generate the calibration images with different sizes. 30 31 It generates the SVG images which are easy to be produced by changing its 32 XML text content. 33 34 """ 35 36 TEMPLATE_WIDTH = 1680 37 TEMPLATE_HEIGHT = 1052 38 TEMPLATE_FILENAME = 'template-%dx%d.svg' % (TEMPLATE_WIDTH, TEMPLATE_HEIGHT) 39 GS_URL = ('http://commondatastorage.googleapis.com/chromeos-localmirror/' 40 'distfiles/chameleon_calibration_images') 41 42 43 def __init__(self): 44 """Construct an ImageGenerator. 45 """ 46 module_dir = os.path.dirname(sys.modules[__name__].__file__) 47 template_path = os.path.join(module_dir, 'calibration_images', 48 self.TEMPLATE_FILENAME) 49 self._image_template = open(template_path).read() 50 51 52 def generate_image(self, width, height, filename): 53 """Generate the image with the given width and height. 54 55 @param width: The width of the image. 56 @param height: The height of the image. 57 @param filename: The filename to output, svg file or png file. 58 """ 59 if filename.endswith('.svg'): 60 with open(filename, 'w+') as f: 61 logging.debug('Generate the image with size %dx%d to %s', 62 width, height, filename) 63 f.write(self._image_template.format( 64 scale_width=float(width)/self.TEMPLATE_WIDTH, 65 scale_height=float(height)/self.TEMPLATE_HEIGHT)) 66 elif filename.endswith('.png'): 67 pregen_filename = 'image-%dx%d.png' % (width, height) 68 pregen_path = os.path.join(self.GS_URL, pregen_filename) 69 logging.debug('Fetch the image from: %s', pregen_path) 70 if utils.system('wget -q -O %s %s' % (filename, pregen_path), 71 ignore_status=True): 72 raise ImageGeneratorError('Failed to fetch the image: %s' % 73 pregen_filename) 74 else: 75 raise ImageGeneratorError('The image format not supported') 76 77 @staticmethod 78 def get_extrema(image): 79 """Returns a 2-tuple containing minimum and maximum values of the image. 80 81 @param image: the calibration image projected by DUT. 82 @return a tuple of (minimum, maximum) 83 """ 84 w, h = image.size 85 min_value = 255 86 max_value = 0 87 # scan the middle vertical line 88 x = w // 2 89 for i in range(0, h // 2): 90 v = image.getpixel((x, i))[0] 91 if v < min_value: 92 min_value = v 93 if v > max_value: 94 max_value = v 95 return (min_value, max_value) 96 97 98if __name__ == '__main__': 99 parser = argparse.ArgumentParser() 100 parser.add_argument('output', type=str, 101 help='filename of the calibration image') 102 args = parser.parse_args() 103 104 matched = re.search(r'image-(\d+)x(\d+).(png|svg)', args.output) 105 if not matched: 106 logging.error('The filename should be like: image-1920x1080.svg') 107 parser.print_help() 108 sys.exit(errno.EINVAL) 109 110 width = int(matched.group(1)) 111 height = int(matched.group(2)) 112 generator = ImageGenerator() 113 generator.generate_image(width, height, args.output) 114