def screen_record_v3(): last_time = time.time() while 1: region = CG.CGRectMake(100, 100, 400, 400) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) prov = CG.CGImageGetDataProvider(image) data = CG.CGDataProviderCopyData(prov) byteperrow = CG.CGImageGetBytesPerRow(image) #print prov #<CGDataProvider 0x7fc19b1022f0> #print type(data) #<objective-c class __NSCFData at 0x7fff78073cf8> img = np.frombuffer(data, dtype=np.uint8) img = img.reshape((height, byteperrow//4,4)) img = img[:, :width, :] print('loop took {0} seconds' . format(time.time()-last_time)) img = process_img(img) # the above take roughly 0.01s last_time = time.time() cv2.imshow('window',img) if cv2.waitKey(25) & 0xFF == ord('q'): cv2.destroyAllWindows() break
def screenshot(region=None, dpi=72, cv2_format=False): if region is None: region = CG.CGRectInfinite else: region = CG.CGRectMake(*region) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) file_name = '.screenshot-{0}.png'.format( datetime.datetime.now().strftime('%Y-%m%d_%H-%M-%S-%f')) file_type = LaunchServices.kUTTypePNG file_url = NSURL.fileURLWithPath_(file_name) dest = Quartz.CGImageDestinationCreateWithURL(file_url, file_type, 1, None) properties = { Quartz.kCGImagePropertyDPIWidth: dpi, Quartz.kCGImagePropertyDPIHeight: dpi, } Quartz.CGImageDestinationAddImage(dest, image, properties) Quartz.CGImageDestinationFinalize(dest) if cv2_format: image = cv2.imread(file_name) else: image = Image.open(file_name) os.unlink(file_name) return image
def capture(self, region=None): """region should be a CGRect, something like: >>> import Quartz.CoreGraphics as cg >>> region = cg.CGRectMake(0, 0, 100, 100) >>> sp = _MacAdapter() >>> sp.capture(region=region) The default region is CG.CGRectInfinite (captures the full screen) """ if region is None: region = cg.CGRectInfinite else: if not isinstance(region, (list, tuple)): raise AttributeError("Capture region must be a list or tuple") if region[0] % 2 > 0: raise ValueError( "Capture region width should be even (was %s)" % region[0]) region = cg.CGRectMake(0, 0, region[0], region[1]) image = cg.CGWindowListCreateImage(region, cg.kCGWindowListOptionOnScreenOnly, cg.kCGNullWindowID, cg.kCGWindowImageDefault) width = cg.CGImageGetWidth(image) height = cg.CGImageGetHeight(image) provider = cg.CGImageGetDataProvider(image) data = cg.CGDataProviderCopyData(provider) return data, width, height
def take_screenshot(self, x, y, w, h, hwnd=None): """ get area screenshot Args: x, y: top-left corner of a rectangle w, h: rectangle dimensions hwnd: for compatibility Returns: numpy array http://stackoverflow.com/questions/37359192/cannot-figure-out-numpy-equivalent-for-cv-mat-step0 """ [x, y, w, h] = map(int, [x, y, w, h]) driver_cache_size = 64 # bytes # align width to the nearest value that divisible by driver_cache_size if w % driver_cache_size != 0: w = driver_cache_size * (int(w / driver_cache_size) + 1) image_ref = CG.CGWindowListCreateImage( CG.CGRectMake(x, y, w, h), # CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) pixeldata = CG.CGDataProviderCopyData( CG.CGImageGetDataProvider(image_ref)) height = CG.CGImageGetHeight(image_ref) width = CG.CGImageGetWidth(image_ref) image = Image.frombuffer("RGBA", (width, height), pixeldata, "raw", "RGBA", 0, 1).convert('RGB') return np.array(image)
def screenshot(*args): if len(args) == 4: x, y, w, h = args elif len(args) == 3 and isinstance(args[0], Point): x, y = args[0] w, h = args[1:] else: raise Exception('Error! Bad input to screenshot.') norm_w = SCREENSHOT_WIDTHS[np.searchsorted(SCREENSHOT_WIDTHS, w)] region = CG.CGRectMake(x, y, norm_w, h) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) provider = CG.CGImageGetDataProvider(image) bin_data = CG.CGDataProviderCopyData(provider) data_format = "%dB" % norm_w * h * 4 unpacked = struct.unpack_from(data_format, bin_data) if norm_w == w: return np.array(unpacked, dtype=np.uint8).reshape(h, w, 4) else: return np.array(unpacked, dtype=np.uint8).reshape(h, norm_w, 4)[:, :w]
def scoreGrab(dy): """Captures an image of the scoreboard and converts it to RGB array. Returns scoreboard readings from ScoreReading.py scoreBoard() method.""" region = CG.CGRectMake(434, 142 + dy, 190, 88) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) bytesperrow = CG.CGImageGetBytesPerRow(image) pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(image)) array = np.frombuffer(pixeldata, dtype=np.uint8) array = array.reshape((height, bytesperrow // 4, 4)) array = array[:, :, [2, 1, 0]][:, :width, :] r, g, b = array.T grey = (r == 196) & (g == 196) & (b == 196) array[:, :, :3][grey.T] = (0, 0, 0) other = (r > 0) & (g >= 0) & (b > 0) array[:, :, :3][other.T] = (255, 255, 255) return array, sr.scoreBoard(array)
def get_CG_imagewrapper(rect=None): from xpra.codecs.image_wrapper import ImageWrapper assert CG, "cannot capture without Quartz.CoreGraphics" if rect is None: x = 0 y = 0 region = CG.CGRectInfinite else: x, y, w, h = rect region = CG.CGRectMake(x, y, roundup(w, 2), roundup(h, 2)) image = CG.CGWindowListCreateImage( region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageNominalResolution) #CG.kCGWindowImageDefault) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) bpc = CG.CGImageGetBitsPerComponent(image) bpp = CG.CGImageGetBitsPerPixel(image) rowstride = CG.CGImageGetBytesPerRow(image) alpha = CG.CGImageGetAlphaInfo(image) alpha_str = ALPHA.get(alpha, alpha) log( "get_CG_imagewrapper(..) image size: %sx%s, bpc=%s, bpp=%s, rowstride=%s, alpha=%s", width, height, bpc, bpp, rowstride, alpha_str) prov = CG.CGImageGetDataProvider(image) argb = CG.CGDataProviderCopyData(prov) return ImageWrapper(x, y, width, height, argb, "BGRX", 24, rowstride)
def comp_run_time(): """Compare the running time of different screenshot methods """ import contextlib @contextlib.contextmanager def timer(msg): start = time.time() yield end = time.time() print("%s: %.02fms" % (msg, (end - start) * 1000)) with timer("v1.capture"): region = (30, 230, 700, 400) im1 = get_screenshot_v1(region=region) with timer("v1.save"): im1.save("screen_v1.png") with timer("v2"): region = CG.CGRectMake(10, 120, 344, 80) im2 = get_screenshot_v2(region=region) with timer("v2.save"): im2.save("screen_v2.png")
def main(): # comp_run_time() # Record starttime start = time.time() # Region for screenshot # The values are tuned for iphone7 & MacBook Pro (Retina, 15-inch, Mid 2014) # v1: # region = (30,230,700,400) # im = get_screenshot_v1(region=region) # v2: region = CG.CGRectMake(10, 120, 344, 180) im = get_screenshot_v2(region=region) # im.save("images/screen_v1.png") # OCR text recognition text = pytesseract.image_to_string(im, lang='chi_sim') text = ''.join(text.split(" ")) # print(text) # Create Baidu URL and visit url = 'http://www.baidu.com/s?wd=%s' % text # print(url) web = webbrowser.get("chrome") # need to specify brower code in Mac OS web.open(url) # subprocess.call(["open", url]) # Record endtime end = time.time() print(end - start)
def capture(self): # Region size is hard coded, please change it # as per your need. X = 50 Y = 160 region = CG.CGRectMake(X, Y, 160, 116) if region is None: region = CG.CGRectInfinite else: # Capture region should be even sized else # you will see wrongly strided images i.e corrupted if region.size.width % 2 > 0: emsg = "Capture region width should be even (was %s)" % ( region.size.width) raise ValueError(emsg) # Create screenshot as CGImage image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) # Intermediate step, get pixel data as CGDataProvider prov = CG.CGImageGetDataProvider(image) # Copy data out of CGDataProvider, becomes string of bytes self._data = CG.CGDataProviderCopyData(prov) # Get width/height of image self.width = CG.CGImageGetWidth(image) self.height = CG.CGImageGetHeight(image)
def get_screen_pixel(x, y): image = CG.CGWindowListCreateImage(CoreGraphics.CGRectMake(x, y, 2, 2), CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) bytes = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(image)) b, g, r, a = struct.unpack_from("BBBB", bytes, offset=0) return (r, g, b, a)
def make_screenshot(): global counter region = CG.CGRectMake(28, 46, 640, 640) screenshot_time = time.time() screenshot(FILE_NAME, region=region) # save_screenshot(counter) counter += 1 return FILE_NAME, screenshot_time
def grab_desktop(self, return_type=0): """ grab desktop screenshot. :type return_type: int :param return_type: 0 for pil image, 1 for color matrix, 2 for gray matrix :rtype: numpy.ndarray or Image.Image :return: the screenshot image """ ret_image = None # Create screenshot as CGImage image = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) # Allocate enough space to hold our pixels imageData = objc.allocateBuffer(int(4 * width * height)) # Create the bitmap context bitmapContext = CG.CGBitmapContextCreate( imageData, # image data we just allocated... width, # width height, # height 8, # 8 bits per component 4 * width, # bytes per pixel times number of pixels wide CG.CGImageGetColorSpace( image), # use the same colorspace as the original image CG.kCGImageAlphaPremultipliedLast) # use premultiplied alpha CG.CGContextDrawImage(bitmapContext, CG.CGRectMake(0, 0, width, height), image) #Now your rawData contains the image data in the RGBA8888 pixel format. #del bitmapContext ret_image = Image.frombuffer("RGBA", (width, height), imageData, "raw", "RGBA", 0, 1) #return ret_image #ret_image.save('out.jpg') ret_image = ret_image.convert('RGB') #ret_image.save('out.jpg') if return_type == self.get_color_mat: return self._get_cv_color_mat(ret_image) if return_type == self.get_gray_mat: mat = self._get_cv_color_mat(ret_image) return self._get_cv_gray_mat(mat) else: return ret_image
def get_img_array(box): if box[2] - box[0] < (box[3] - box[1]) * 1.6: region = CG.CGRectMake(box[0], box[1], (box[3] - box[1]) * 1.6, box[3] - box[1]) else: region = CG.CGRectMake(box[0], box[1], box[2] - box[0], (box[2] - box[0]) / 1.6) sp.capture(region=region) pixel_size = len(xxxx) / 4 #img1 = imread("/Users/selfdir/Documents/littlerabbit/material/1.png") nparr = np.fromstring(xxxx, np.uint8) nparr = np.reshape(nparr, (-1, 4)) nparr = np.delete(nparr, 3, 1) if box[2] - box[0] < (box[3] - box[1]) * 1.6: nparr = np.reshape(nparr, (box[3] - box[1], pixel_size / (box[3] - box[1]), 3)) nparr = nparr[0:box[3] - box[1], 0:box[2] - box[0]] else: nparr = np.reshape(nparr, ((box[2] - box[0]) / 1.6, pixel_size / (box[2] - box[0]) * 1.6, 3)) nparr = nparr[0:box[3] - box[1], 0:box[2] - box[0]] return nparr
def __init__(self): # ROI 60% horizontal self.roi_horizontal = 0.60 self.roi = CG.CGRectMake(10, 140, 640 * self.roi_horizontal, 140) self.seq_frames = deque(maxlen=4) game_over_pix_black = np.load("game_over_black.npy") game_over_pix_white = np.load("game_over_white.npy") self.game_over_state = [game_over_pix_black, game_over_pix_white] print("Image processor created...\n")
def get_img(x, y, w, h): region = CG.CGRectMake(x, y, w, h) image = CG.CGWindowListCreateImage(region, 1, 0, 0) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) bytesperrow = CG.CGImageGetBytesPerRow(image) pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(image)) image = np.frombuffer(pixeldata, dtype=np.uint8) image = image.reshape((height, bytesperrow // 4, 4)) im = image[:, :width, :] return im
def screen_record(): region = CG.CGRectMake(100, 122, 400, 378) #image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageNominalResolution) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) prov = CG.CGImageGetDataProvider(image) data = CG.CGDataProviderCopyData(prov) byteperrow = CG.CGImageGetBytesPerRow(image) img = np.frombuffer(data, dtype=np.uint8) img = img.reshape((height, byteperrow//4,4)) img = img[:, :width, :] return img
def get_pixel_data(region: Optional[Region] = None): region = (CoreGraphics.CGRectInfinite if region is None else CoreGraphics.CGRectMake(region.x1, region.y1, region.x2 - region.x1, region.y2 - region.y1)) image = CoreGraphics.CGWindowListCreateImage( region, CoreGraphics.kCGWindowListOptionOnScreenOnly, CoreGraphics.kCGNullWindowID, CoreGraphics.kCGWindowImageDefault, ) pixel_data = CoreGraphics.CGDataProviderCopyData( CoreGraphics.CGImageGetDataProvider(image)) bytes_per_row = CoreGraphics.CGImageGetBytesPerRow(image) // 4 return pixel_data, bytes_per_row
def pixel(self, x, y): region = CG.CGRectMake(x, y, 1, 1) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) prov = CG.CGImageGetDataProvider(image) self._data = CG.CGDataProviderCopyData(prov) self.width = CG.CGImageGetWidth(image) self.height = CG.CGImageGetHeight(image) data_format = "BBBB" b, g, r, a = struct.unpack_from(data_format, self._data, offset=0) return (r, g, b)
def imageGrowLoop(self): img = self.samples[self.currentSample]['screenshot'][:] path = os.path.join(self.datadrive, "screenshots", self.samples[self.currentSample]['screenshot']) cueImage = NSImage.alloc().initByReferencingFile_(path) max_height = min(cueImage.size().height, self.viewH) if (self.cueH <= max_height - 20 and self.growImage): print 'increasing size' self.cueH = self.cueH + 20 self.cueW = self.cueH * self.cueRatio targetImage = NSImage.alloc().initWithSize_( NSMakeSize(self.cueW, self.cueH)) if (self.samples[self.currentSample]['snippet']): x = float(path.split("_")[-2]) y = float(path.split("_")[-1].split('-')[0].split('.')[0]) fromRect = CG.CGRectMake(x - self.cueW / 2, y - self.cueH / 2, self.cueW, self.cueH) toRect = CG.CGRectMake(0.0, 0.0, self.cueW, self.cueH) else: fromRect = CG.CGRectMake(0.0, 0.0, cueImage.size().width, cueImage.size().height) toRect = CG.CGRectMake(0.0, 0.0, self.cueW, self.cueH) targetImage.lockFocus() cueImage.drawInRect_fromRect_operation_fraction_( toRect, fromRect, NSCompositeCopy, 1.0) targetImage.unlockFocus() self.reviewController.mainPanel.setImage_(targetImage) s = objc.selector(self.imageGrowLoop, signature='v@:') self.imageLoop = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( 2, self, s, None, False)
def _grab_to_file(self, filename, bbox=None, dpi=72): # FIXME: Should query dpi from somewhere, e.g for retina displays import Quartz import LaunchServices from Cocoa import NSURL import Quartz.CoreGraphics as CG import objc if bbox: width = bbox[2] - bbox[0] height = bbox[3] - bbox[1] region = CG.CGRectMake(bbox[0], bbox[1], width, height) else: region = CG.CGRectInfinite # Create screenshot as CGImage image = CG.CGWindowListCreateImage( region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault, ) # XXX: Can add more types: # https://developer.apple.com/library/mac/documentation/MobileCoreServices/Reference/UTTypeRef/Reference/reference.html#//apple_ref/doc/uid/TP40008771 file_type = LaunchServices.kUTTypePNG url = NSURL.fileURLWithPath_(filename) dest = Quartz.CGImageDestinationCreateWithURL( url, file_type, # 1 image in file 1, None, ) properties = { Quartz.kCGImagePropertyDPIWidth: dpi, Quartz.kCGImagePropertyDPIHeight: dpi, } # Add the image to the destination, characterizing the image with # the properties dictionary. Quartz.CGImageDestinationAddImage(dest, image, properties) # When all the images (only 1 in this example) are added to the destination, # finalize the CGImageDestination object. Quartz.CGImageDestinationFinalize(dest)
def observationGrab(): """Captures image of the game screen and converts it to RGB array.""" region = CG.CGRectMake(401, 130, 634, 445) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) bytesperrow = CG.CGImageGetBytesPerRow(image) pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(image)) array = np.frombuffer(pixeldata, dtype=np.uint8) array = array.reshape((height, bytesperrow // 4, 4)) array = array[:, :, [2, 1, 0]][:, :width, :] return array
def capture(region, dump=True): start = time.time() if region is not None: sp.capture(CG.CGRectMake(region[0], region[1], region[2], region[3])) else: sp.capture() img = Image.frombytes("RGBA", (sp.width, sp.height), sp.data()) b, g, r, a = img.split() img = Image.merge("RGB", (r, g, b)) if dump: print("capture in {} s".format(time.time() - start)) return img, time.time()
def get_raw_text_from_screen(): """Use OCR to extract raw question and options text """ region = CG.CGRectMake(start_x, start_y, width, height) im = get_screenshot_v2(region=region) q_im = im.crop((0, 0, im.width, q_height)) opt_im = im.crop((0, q_height, im.width / 2, im.height)) # im.save('images/screen_v2.png') # q_im.save("images/question.png") # opt_im.save("images/options.png") # q_im = Image.open("images/question.png") # opt_im = Image.open("images/options.png") question_raw = pytesseract.image_to_string(q_im, lang='chi_sim') options_raw = pytesseract.image_to_string(opt_im, lang='chi_sim') return question_raw, options_raw
def read_values(self): # We capture a vertical slice of the left-hand side of the screen. # This allows us to capture both the top-left and bottom-left pixels cgimg = CG.CGWindowListCreateImage( CG.CGRectMake(0, 0, 1, self.screen_height), CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) width = Quartz.CGImageGetWidth(cgimg) height = Quartz.CGImageGetHeight(cgimg) pixeldata = Quartz.CGDataProviderCopyData( Quartz.CGImageGetDataProvider(cgimg)) bpr = Quartz.CGImageGetBytesPerRow(cgimg) pilimage = Image.frombuffer("RGBA", (width, height), pixeldata, "raw", "BGRA", bpr, 1) return self._extract_mode(pilimage.getpixel( (0, 0))[0]), pilimage.getpixel((0, pilimage.size[1] - 1))[0]
def capture(self, region=None): if region == None: region = CG.CGRectInfinite else: region = CG.CGRectMake(region) image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) provider = CG.CGImageGetDataProvider(image) self._data = CG.CGDataProviderCopyData(provider) self.width = CG.CGImageGetWidth(image) self.height = CG.CGImageGetHeight(image) imgdata = np.fromstring(self._data, dtype=np.uint8).reshape( len(self._data) / 4, 4) return imgdata[:self.width * self.height, :-1].reshape( self.height, self.width, 3)
def _grab_to_file(self, filename, bbox=None, dpi=72): # Should query dpi from somewhere, e.g for retina displays? import Quartz import LaunchServices from Cocoa import NSURL import Quartz.CoreGraphics as CG if bbox: width = bbox[2] - bbox[0] height = bbox[3] - bbox[1] region = CG.CGRectMake(bbox[0], bbox[1], width, height) else: region = CG.CGRectInfinite # Create screenshot as CGImage image = CG.CGWindowListCreateImage( region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault, ) file_type = LaunchServices.kUTTypePNG url = NSURL.fileURLWithPath_(filename) dest = Quartz.CGImageDestinationCreateWithURL( url, file_type, # 1 image in file 1, None, ) properties = { Quartz.kCGImagePropertyDPIWidth: dpi, Quartz.kCGImagePropertyDPIHeight: dpi, } # Add the image to the destination, characterizing the image with # the properties dictionary. Quartz.CGImageDestinationAddImage(dest, image, properties) # When all the images (only 1 in this example) are added to the destination, # finalize the CGImageDestination object. Quartz.CGImageDestinationFinalize(dest)
def screenshot(x, y, w, h): region = CG.CGRectMake(x, y, w, h) # Create screenshot as CGImage image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) width = CG.CGImageGetWidth(image) height = CG.CGImageGetHeight(image) bytesperrow = CG.CGImageGetBytesPerRow(image) pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(image)) image = np.frombuffer(pixeldata, dtype=np.uint8) image = image.reshape((height, bytesperrow // 4, 4)) return image[:, :width, :]
def capture(self): region = CG.CGRectMake(x, y, 1, 1) # Create screenshot as CGImage image = CG.CGWindowListCreateImage(region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) # Intermediate step, get pixel data as CGDataProvider prov = CG.CGImageGetDataProvider(image) # Copy data out of CGDataProvider, becomes string of bytes self._data = CG.CGDataProviderCopyData(prov) # Get width/height of image self.width = CG.CGImageGetWidth(image) self.height = CG.CGImageGetHeight(image)
def screenshot(path, region=None): """saves screenshot of given region to path :path: string path to save to :region: tuple of (x, y, width, height) :returns: nothing """ if region is None: region = CG.CGRectInfinite else: region = CG.CGRectMake(*region) # Create screenshot as CGImage image = CG.CGWindowListCreateImage( region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) dpi = 72 # FIXME: Should query this from somewhere, e.g for retina displays url = NSURL.fileURLWithPath_(path) dest = Quartz.CGImageDestinationCreateWithURL( url, LaunchServices.kUTTypePNG, # file type 1, # 1 image in file None ) properties = { Quartz.kCGImagePropertyDPIWidth: dpi, Quartz.kCGImagePropertyDPIHeight: dpi, } # Add the image to the destination, characterizing the image with # the properties dictionary. Quartz.CGImageDestinationAddImage(dest, image, properties) # When all the images (only 1 in this example) are added to the destination, # finalize the CGImageDestination object. Quartz.CGImageDestinationFinalize(dest)