def save_screenshot(self, path): """ Get and save screenshot of element or window. :param path: path to save the screenshot file; eg. screen.png, /path/to/image.png """ from atomac.ldtpd.generic import Generic from cStringIO import StringIO from PIL import Image # capture the app window screen and load it as Image using PIL generic = Generic() image_base64_string = generic.imagecapture( window_name=self.app.windows()[0].AXTitle) image = StringIO(image_base64_string.decode('base64')) image = Image.open(image) # get app window position app_pos_x, app_pos_y = self.app.windows()[0].AXPosition # get element position and size elem_pos_x, elem_pos_y = self.get_element().AXPosition elem_size_x, elem_size_y = self.get_element().AXSize # count element's relative position pos_x = elem_pos_x - app_pos_x pos_y = elem_pos_y - app_pos_y # crop and save the image image = image.crop((int(pos_x), int(pos_y), int(pos_x + elem_size_x), int(pos_y + elem_size_y))) image.save(path)
def scaleImage(image, width=None, height=None, direction="down", quality=88, result=None): """Scale an image to another size. The generated image is a JPEG image, unless the original is a PNG image. This is needed to make sure alpha channel information is not lost, which JPEG does not support. Three different scaling options are supported: * `up` scaling scales the smallest dimension up to the required size and scrops the other dimension if needed. * `down` scaling starts by scaling the largest dimension to the required size and scrops the other dimension if needed. * `thumbnail` scales to the requested dimensions without cropping. The resulting image may have a different size than requested. This option requires both width and height to be specified. `keep` is accepted as an alternative spelling for this option, but its use is deprecated. The `image` parameter can either be the raw image data (ie a `str` instance) or an open file. The `quality` parameter can be used to set the quality of the resulting image scales. The return value is a tuple with the new image, the image format and a size-tuple. Optionally a file-like object can be given as the `result` parameter, in which the generated image scale will be stored. """ if direction=="keep": direction="thumbnail" if direction=="thumbnail" and not (width and height): raise ValueError("Thumbnailing requires both width and height to be specified") elif width is None and height is None: raise ValueError("Either width or height need to be given") if isinstance(image, str): image=StringIO(image) image=PIL.Image.open(image) if image.mode=="1": # Convert black&white to grayscale image=image.convert("L") elif image.mode=="P": # Convert palette based images to 3x8bit+alpha image=image.convert("RGBA") elif image.mode=="CMYK": # Convert CMYK to RGB, allowing for web previews of print images image=image.convert("RGB") # When we create a new image during scaling we loose the format # information, so remember it here. image_format=image.format current_size=image.size # Determine scale factor needed to get the right height if height is None: scale_height=None else: scale_height=(float(height)/float(current_size[1])) if width is None: scale_width=None else: scale_width=(float(width)/float(current_size[0])) if scale_height==scale_width or direction=="thumbnail": # The original already has the right aspect ratio, so we only need # to scale. image.thumbnail((width, height), PIL.Image.ANTIALIAS) else: if direction=="down": if scale_height is None or (scale_width is not None and scale_width>scale_height): # Width is the smallest dimension (relatively), so scale up # to the desired width new_width=width new_height=int(round(current_size[1]*scale_width)) else: new_height=height new_width=int(round(current_size[0]*scale_height)) else: if scale_height is None or (scale_width is not None and scale_width<scale_height): # Width is the largest dimension (relatively), so scale up # to the desired width new_width=width new_height=int(round(current_size[1]*scale_width)) else: new_height=height new_width=int(round(current_size[0]*scale_height)) image.draft(image.mode, (new_width, new_height)) image=image.resize((new_width, new_height), PIL.Image.ANTIALIAS) if (width is not None and new_width>width) or (height is not None and new_height>height): if width is None: left=0 right=new_width else: left=int((new_width-width)/2.0) right=left+width if height is None: height=new_height image=image.crop((left, 0, right, height)) if image_format=="PNG": format="PNG" else: format="JPEG" if result is None: result=StringIO() image.save(result, format, quality=quality, optimize=True) result=result.getvalue() else: image.save(result, format, quality=quality, optimize=True) result.seek(0) return (result, format, image.size)