1*9c5db199SXin Li# Copyright 2014 The Chromium OS Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li 5*9c5db199SXin Li"""Classes to do screen capture.""" 6*9c5db199SXin Li 7*9c5db199SXin Liimport logging 8*9c5db199SXin Li 9*9c5db199SXin Lifrom PIL import Image 10*9c5db199SXin Li 11*9c5db199SXin Lifrom autotest_lib.client.cros.multimedia import image_generator 12*9c5db199SXin Li 13*9c5db199SXin Li 14*9c5db199SXin Lidef _unlevel(p): 15*9c5db199SXin Li """Unlevel a color value from TV level back to PC level 16*9c5db199SXin Li 17*9c5db199SXin Li @param p: The color value in one character byte 18*9c5db199SXin Li 19*9c5db199SXin Li @return: The color value in integer in PC level 20*9c5db199SXin Li """ 21*9c5db199SXin Li # TV level: 16~236; PC level: 0~255 22*9c5db199SXin Li p = (p - 126) * 128 // 110 + 128 23*9c5db199SXin Li if p < 0: 24*9c5db199SXin Li p = 0 25*9c5db199SXin Li elif p > 255: 26*9c5db199SXin Li p = 255 27*9c5db199SXin Li return p 28*9c5db199SXin Li 29*9c5db199SXin Li 30*9c5db199SXin Liclass CommonChameleonScreenCapturer(object): 31*9c5db199SXin Li """A class to capture the screen on Chameleon. 32*9c5db199SXin Li 33*9c5db199SXin Li Calling its member method capture() captures the screen. 34*9c5db199SXin Li 35*9c5db199SXin Li """ 36*9c5db199SXin Li TAG = 'Chameleon' 37*9c5db199SXin Li 38*9c5db199SXin Li def __init__(self, chameleon_port): 39*9c5db199SXin Li """Initializes the CommonChameleonScreenCapturer objects.""" 40*9c5db199SXin Li self._chameleon_port = chameleon_port 41*9c5db199SXin Li 42*9c5db199SXin Li 43*9c5db199SXin Li def capture(self): 44*9c5db199SXin Li """Captures the screen. 45*9c5db199SXin Li 46*9c5db199SXin Li @return An Image object. 47*9c5db199SXin Li """ 48*9c5db199SXin Li logging.info('Capturing the screen on Chameleon...') 49*9c5db199SXin Li image = self._chameleon_port.capture_screen() 50*9c5db199SXin Li 51*9c5db199SXin Li # unleveling from TV level [16, 235] 52*9c5db199SXin Li pmin, pmax = image_generator.ImageGenerator.get_extrema(image) 53*9c5db199SXin Li if pmin > 10 and pmax < 240: 54*9c5db199SXin Li logging.info(' (TV level: %d %d)', pmin, pmax) 55*9c5db199SXin Li image = Image.eval(image, _unlevel) 56*9c5db199SXin Li return image 57*9c5db199SXin Li 58*9c5db199SXin Li 59*9c5db199SXin Liclass VgaChameleonScreenCapturer(object): 60*9c5db199SXin Li """A class to capture the screen on a VGA port of Chameleon. 61*9c5db199SXin Li 62*9c5db199SXin Li Calling its member method capture() captures the screen. 63*9c5db199SXin Li 64*9c5db199SXin Li """ 65*9c5db199SXin Li TAG = 'Chameleon' 66*9c5db199SXin Li 67*9c5db199SXin Li def __init__(self, chameleon_port): 68*9c5db199SXin Li """Initializes the VgaChameleonScreenCapturer objects.""" 69*9c5db199SXin Li self._chameleon_port = chameleon_port 70*9c5db199SXin Li 71*9c5db199SXin Li 72*9c5db199SXin Li def capture(self): 73*9c5db199SXin Li """Captures the screen. 74*9c5db199SXin Li 75*9c5db199SXin Li @return An Image object. 76*9c5db199SXin Li """ 77*9c5db199SXin Li logging.info('Capturing the screen on a VGA port of Chameleon...') 78*9c5db199SXin Li image = self._chameleon_port.capture_screen() 79*9c5db199SXin Li 80*9c5db199SXin Li # Find the box containing white points on its boundary. 81*9c5db199SXin Li boundary = image.convert('L').point( 82*9c5db199SXin Li lambda x: 255 if x >= 220 else 0).getbbox() 83*9c5db199SXin Li logging.info('Boundary: %r', boundary) 84*9c5db199SXin Li image = image.crop(boundary) 85*9c5db199SXin Li return image 86*9c5db199SXin Li 87*9c5db199SXin Li 88*9c5db199SXin Liclass CrosExternalScreenCapturer(object): 89*9c5db199SXin Li """A class to capture the external screen on ChromeOS. 90*9c5db199SXin Li 91*9c5db199SXin Li Calling its member method capture() captures the screen. 92*9c5db199SXin Li 93*9c5db199SXin Li """ 94*9c5db199SXin Li TAG = 'CrOS-Ext' 95*9c5db199SXin Li 96*9c5db199SXin Li def __init__(self, display_facade): 97*9c5db199SXin Li """Initializes the CrosExternalScreenCapturer objects.""" 98*9c5db199SXin Li self._display_facade = display_facade 99*9c5db199SXin Li 100*9c5db199SXin Li 101*9c5db199SXin Li def capture(self): 102*9c5db199SXin Li """Captures the screen. 103*9c5db199SXin Li 104*9c5db199SXin Li @return An Image object. 105*9c5db199SXin Li """ 106*9c5db199SXin Li logging.info('Capturing the external screen on CrOS...') 107*9c5db199SXin Li return self._display_facade.capture_external_screen() 108*9c5db199SXin Li 109*9c5db199SXin Li 110*9c5db199SXin Liclass CrosInternalScreenCapturer(object): 111*9c5db199SXin Li """A class to capture the internal screen on ChromeOS. 112*9c5db199SXin Li 113*9c5db199SXin Li Calling its member method capture() captures the screen. 114*9c5db199SXin Li 115*9c5db199SXin Li """ 116*9c5db199SXin Li TAG = 'CrOS-Int' 117*9c5db199SXin Li 118*9c5db199SXin Li def __init__(self, display_facade): 119*9c5db199SXin Li """Initializes the CrosInternalScreenCapturer objects.""" 120*9c5db199SXin Li self._display_facade = display_facade 121*9c5db199SXin Li 122*9c5db199SXin Li 123*9c5db199SXin Li def capture(self): 124*9c5db199SXin Li """Captures the screen. 125*9c5db199SXin Li 126*9c5db199SXin Li @return An Image object. 127*9c5db199SXin Li """ 128*9c5db199SXin Li logging.info('Capturing the internal screen on CrOS...') 129*9c5db199SXin Li return self._display_facade.capture_internal_screen() 130*9c5db199SXin Li 131*9c5db199SXin Li 132*9c5db199SXin Liclass CrosCalibrationImageCapturer(object): 133*9c5db199SXin Li """A class to capture the calibration image on ChromeOS. 134*9c5db199SXin Li 135*9c5db199SXin Li Calling its member method capture() captures the image. 136*9c5db199SXin Li 137*9c5db199SXin Li """ 138*9c5db199SXin Li TAG = 'Calibration' 139*9c5db199SXin Li 140*9c5db199SXin Li def __init__(self, display_facade): 141*9c5db199SXin Li """Initializes the CrosCalibrationImageCapturer objects.""" 142*9c5db199SXin Li self._display_facade = display_facade 143*9c5db199SXin Li 144*9c5db199SXin Li 145*9c5db199SXin Li def capture(self): 146*9c5db199SXin Li """Captures the screen. 147*9c5db199SXin Li 148*9c5db199SXin Li @return An Image object. 149*9c5db199SXin Li """ 150*9c5db199SXin Li logging.info('Capturing the calibration image on CrOS...') 151*9c5db199SXin Li return self._display_facade.capture_calibration_image() 152