def pillow_imagegrab_screenshot(): img = ImageGrab.grab() out = StringIOClass() img.save(out, format="PNG") v = out.getvalue() out.close() return (img.width, img.height, "png", img.width * 3, v)
def pillow_imagegrab_screenshot(): img = ImageGrab.grab() out = StringIOClass() img.save(out, format="PNG") v = out.getvalue() out.close() return (img.width, img.height, "png", img.width*3, v)
def main(filename): from xpra.os_util import StringIOClass, memoryview_to_bytes from xpra.gtk_common.gtk_util import get_default_root_window, get_root_size root = get_default_root_window() capture = setup_capture(root) capture.refresh() w, h = get_root_size() image = capture.get_image(0, 0, w, h) from PIL import Image fmt = image.get_pixel_format().replace("X", "A") pixels = memoryview_to_bytes(image.get_pixels()) log("converting %i bytes in format %s to RGBA", len(pixels), fmt) if len(fmt) == 3: target = "RGB" else: target = "RGBA" pil_image = Image.frombuffer(target, (w, h), pixels, "raw", fmt, image.get_rowstride()) if target != "RGB": pil_image = pil_image.convert("RGB") buf = StringIOClass() pil_image.save(buf, "png") data = buf.getvalue() buf.close() with open(filename, "wb") as f: f.write(data) return 0
def take_screenshot(self): log("grabbing screenshot") import Image w, h = self.get_dimensions() image = self.get_image(0, 0, w, h) img = Image.frombuffer("RGB", (w, h), image.get_pixels(), "raw", image.get_pixel_format(), image.get_rowstride()) buf = StringIOClass() img.save(buf, "PNG") data = buf.getvalue() buf.close() return w, h, "png", image.get_rowstride(), data
def take_screenshot(self): from PIL import Image x, y, w, h = self.get_metrics() image = self.get_image(x, y, w, h) assert image.get_width()==w and image.get_height()==h assert image.get_pixel_format()=="BGRX" img = Image.frombuffer("RGB", (w, h), image.get_pixels(), "raw", "BGRX", 0, 1) out = StringIOClass() img.save(out, format="PNG") screenshot = (img.width, img.height, "png", img.width*3, out.getvalue()) out.close() return screenshot
def take_screenshot(self): from PIL import Image #@UnresolvedImport x, y, w, h = get_virtualscreenmetrics() image = self.get_image(x, y, w, h) assert image.get_width()==w and image.get_height()==h assert image.get_pixel_format()=="BGRX" img = Image.frombuffer("RGB", (w, h), image.get_pixels(), "raw", "BGRX", 0, 1) out = StringIOClass() img.save(out, format="PNG") screenshot = (img.width, img.height, "png", img.width*3, out.getvalue()) out.close() return screenshot
def make_screenshot_packet_from_regions(self, regions): #regions = array of (wid, x, y, PIL.Image) if not regions: log("screenshot: no regions found, returning empty 0x0 image!") return ["screenshot", 0, 0, "png", -1, ""] #in theory, we could run the rest in a non-UI thread since we're done with GTK.. minx = min(x for (_, x, _, _) in regions) miny = min(y for (_, _, y, _) in regions) maxx = max((x + img.get_width()) for (_, x, _, img) in regions) maxy = max((y + img.get_height()) for (_, _, y, img) in regions) width = maxx - minx height = maxy - miny log("screenshot: %sx%s, min x=%s y=%s", width, height, minx, miny) from PIL import Image #@UnresolvedImport screenshot = Image.new("RGBA", (width, height)) for wid, x, y, img in reversed(regions): pixel_format = img.get_pixel_format() target_format = { "XRGB": "RGB", "BGRX": "RGB", "BGRA": "RGBA" }.get(pixel_format, pixel_format) pixels = img.get_pixels() w = img.get_width() h = img.get_height() #PIL cannot use the memoryview directly: if isinstance(pixels, memoryview): pixels = pixels.tobytes() try: window_image = Image.frombuffer(target_format, (w, h), pixels, "raw", pixel_format, img.get_rowstride()) except Exception: log.error( "Error parsing window pixels in %s format for window %i", pixel_format, wid, exc_info=True) continue tx = x - minx ty = y - miny screenshot.paste(window_image, (tx, ty)) buf = StringIOClass() screenshot.save(buf, "png") data = buf.getvalue() buf.close() packet = [ "screenshot", width, height, "png", width * 4, Compressed("png", data) ] log("screenshot: %sx%s %s", packet[1], packet[2], packet[-1]) return packet
def take_screenshot(): log("grabbing screenshot") from PIL import Image from xpra.os_util import StringIOClass image = get_CG_imagewrapper() w = image.get_width() h = image.get_height() img = Image.frombuffer("RGB", (w, h), image.get_pixels(), "raw", image.get_pixel_format(), image.get_rowstride()) buf = StringIOClass() img.save(buf, "PNG") data = buf.getvalue() buf.close() return w, h, "png", image.get_rowstride(), data
def take_screenshot(): log("grabbing screenshot") from PIL import Image #@UnresolvedImport from xpra.os_util import StringIOClass image = get_CG_imagewrapper() w = image.get_width() h = image.get_height() img = Image.frombuffer("RGB", (w, h), image.get_pixels(), "raw", image.get_pixel_format(), image.get_rowstride()) buf = StringIOClass() img.save(buf, "PNG") data = buf.getvalue() buf.close() return w, h, "png", image.get_rowstride(), data
def make_screenshot_packet_from_regions(self, regions): #regions = array of (wid, x, y, PIL.Image) if len(regions)==0: log("screenshot: no regions found, returning empty 0x0 image!") return ["screenshot", 0, 0, "png", -1, ""] #in theory, we could run the rest in a non-UI thread since we're done with GTK.. minx = min([x for (_,x,_,_) in regions]) miny = min([y for (_,_,y,_) in regions]) maxx = max([(x+img.get_width()) for (_,x,_,img) in regions]) maxy = max([(y+img.get_height()) for (_,_,y,img) in regions]) width = maxx-minx height = maxy-miny log("screenshot: %sx%s, min x=%s y=%s", width, height, minx, miny) from PIL import Image #@UnresolvedImport screenshot = Image.new("RGBA", (width, height)) for wid, x, y, img in reversed(regions): pixel_format = img.get_pixel_format() target_format = { "XRGB" : "RGB", "BGRX" : "RGB", "BGRA" : "RGBA"}.get(pixel_format, pixel_format) pixels = img.get_pixels() w = img.get_width() h = img.get_height() #PIL cannot use the memoryview directly: if _memoryview and isinstance(pixels, _memoryview): pixels = pixels.tobytes() try: window_image = Image.frombuffer(target_format, (w, h), pixels, "raw", pixel_format, img.get_rowstride()) except: log.error("Error parsing window pixels in %s format for window %i", pixel_format, wid, exc_info=True) continue tx = x-minx ty = y-miny screenshot.paste(window_image, (tx, ty)) buf = StringIOClass() screenshot.save(buf, "png") data = buf.getvalue() buf.close() packet = ["screenshot", width, height, "png", width*4, Compressed("png", data)] log("screenshot: %sx%s %s", packet[1], packet[2], packet[-1]) return packet
def NetWMIcons(disp, data): icons = [] stream = StringIOClass(data) while True: size_image = _read_image(disp, stream) if size_image is None: break icons.append(size_image) if not icons: return None icons.sort() return icons[-1][1]
def do_make_screenshot_packet(self): debug = log.debug debug("grabbing screenshot") regions = [] OR_regions = [] for wid in reversed(sorted(self._id_to_window.keys())): window = self._id_to_window.get(wid) debug("screenshot: window(%s)=%s", wid, window) if window is None: continue if window.is_tray(): debug("screenshot: skipping tray window %s", wid) continue if not window.is_managed(): debug("screenshot: window %s is not/no longer managed", wid) continue if window.is_OR(): x, y = window.get_property("geometry")[:2] else: x, y = self._desktop_manager.window_geometry(window)[:2] debug("screenshot: position(%s)=%s,%s", window, x, y) w, h = window.get_dimensions() debug("screenshot: size(%s)=%sx%s", window, w, h) try: img = trap.call_synced(window.get_image, 0, 0, w, h) except: log.warn("screenshot: window %s could not be captured", wid) continue if img is None: log.warn("screenshot: no pixels for window %s", wid) continue debug("screenshot: image=%s, size=%s", (img, img.get_size())) if img.get_pixel_format() not in ("RGB", "RGBA", "XRGB", "BGRX", "ARGB", "BGRA"): log.warn("window pixels for window %s using an unexpected rgb format: %s", wid, img.get_pixel_format()) continue item = (wid, x, y, img) if window.is_OR(): OR_regions.append(item) elif self._has_focus==wid: #window with focus first (drawn last) regions.insert(0, item) else: regions.append(item) all_regions = OR_regions+regions if len(all_regions)==0: debug("screenshot: no regions found, returning empty 0x0 image!") return ["screenshot", 0, 0, "png", -1, ""] debug("screenshot: found regions=%s, OR_regions=%s", len(regions), len(OR_regions)) #in theory, we could run the rest in a non-UI thread since we're done with GTK.. minx = min([x for (_,x,_,_) in all_regions]) miny = min([y for (_,_,y,_) in all_regions]) maxx = max([(x+img.get_width()) for (_,x,_,img) in all_regions]) maxy = max([(y+img.get_height()) for (_,_,y,img) in all_regions]) width = maxx-minx height = maxy-miny debug("screenshot: %sx%s, min x=%s y=%s", width, height, minx, miny) from PIL import Image #@UnresolvedImport screenshot = Image.new("RGBA", (width, height)) for wid, x, y, img in reversed(all_regions): pixel_format = img.get_pixel_format() target_format = { "XRGB" : "RGB", "BGRX" : "RGB", "BGRA" : "RGBA"}.get(pixel_format, pixel_format) try: window_image = Image.frombuffer(target_format, (w, h), img.get_pixels(), "raw", pixel_format, img.get_rowstride()) except: log.warn("failed to parse window pixels in %s format", pixel_format) continue tx = x-minx ty = y-miny screenshot.paste(window_image, (tx, ty)) buf = StringIOClass() screenshot.save(buf, "png") data = buf.getvalue() buf.close() packet = ["screenshot", width, height, "png", width*4, Compressed("png", data)] debug("screenshot: %sx%s %s", packet[1], packet[2], packet[-1]) return packet
#and we save the compressed data then discard the image im = PIL.Image.frombuffer(rgb, (w, h), image.get_pixels(), "raw", pixel_format, image.get_rowstride()) if coding.startswith( "png") and not supports_transparency and rgb == "RGBA": im = im.convert("RGB") rgb = "RGB" bpp = 24 except Exception, e: log.error("PIL_encode(%s) converting to %s failed", (w, h, coding, "%s bytes" % image.get_size(), pixel_format, image.get_rowstride()), rgb, exc_info=True) raise e buf = StringIOClass() client_options = {} if coding == "jpeg": q = int(min(99, max(1, quality))) kwargs = im.info kwargs["quality"] = q im.save(buf, "JPEG", **kwargs) client_options["quality"] = q else: assert coding in ("png", "png/P", "png/L"), "unsupported png encoding: %s" % coding if coding in ("png/L", "png/P") and supports_transparency and rgb == "RGBA": #grab alpha channel (the last one): #we use the last channel because we know it is RGBA, #otherwise we should do: alpha_index= image.getbands().index('A')
def PIL_encode(coding, image, quality, speed, supports_transparency): assert PIL is not None, "Python PIL is not available" pixel_format = image.get_pixel_format() w = image.get_width() h = image.get_height() rgb = { "XRGB": "RGB", "BGRX": "RGB", "RGBA": "RGBA", "BGRA": "RGBA", }.get(pixel_format, pixel_format) bpp = 32 #remove transparency if it cannot be handled: try: #PIL cannot use the memoryview directly: pixels = memoryview_to_bytes(image.get_pixels()) #it is safe to use frombuffer() here since the convert() #calls below will not convert and modify the data in place #and we save the compressed data then discard the image im = PIL.Image.frombuffer(rgb, (w, h), pixels, "raw", pixel_format, image.get_rowstride()) if coding.startswith( "png") and not supports_transparency and rgb == "RGBA": im = im.convert("RGB") rgb = "RGB" bpp = 24 except Exception as e: log.error("PIL_encode(%s) converting to %s failed", (w, h, coding, "%s bytes" % image.get_size(), pixel_format, image.get_rowstride()), rgb, exc_info=True) raise e buf = StringIOClass() client_options = {} #only optimize with Pillow>=2.2 and when speed is zero if coding in ("jpeg", "webp"): q = int(min(99, max(1, quality))) kwargs = im.info kwargs["quality"] = q client_options["quality"] = q if coding == "jpeg" and PIL_can_optimize and speed < 70: #(optimizing jpeg is pretty cheap and worth doing) kwargs["optimize"] = True client_options["optimize"] = True im.save(buf, coding.upper(), **kwargs) else: assert coding in ("png", "png/P", "png/L"), "unsupported png encoding: %s" % coding if coding in ("png/L", "png/P") and supports_transparency and rgb == "RGBA": #grab alpha channel (the last one): #we use the last channel because we know it is RGBA, #otherwise we should do: alpha_index= image.getbands().index('A') alpha = im.split()[-1] #convert to simple on or off mask: #set all pixel values below 128 to 255, and the rest to 0 def mask_value(a): if a <= 128: return 255 return 0 mask = PIL.Image.eval(alpha, mask_value) else: #no transparency mask = None if coding == "png/L": im = im.convert("L", palette=PIL.Image.ADAPTIVE, colors=255) bpp = 8 elif coding == "png/P": #I wanted to use the "better" adaptive method, #but this does NOT work (produces a black image instead): #im.convert("P", palette=Image.ADAPTIVE) im = im.convert("P", palette=PIL.Image.WEB, colors=255) bpp = 8 if mask: # paste the alpha mask to the color of index 255 im.paste(255, mask) kwargs = im.info if mask is not None: client_options["transparency"] = 255 kwargs["transparency"] = 255 if PIL_can_optimize and speed == 0: #optimizing png is very rarely worth doing kwargs["optimize"] = True client_options["optimize"] = True #level can range from 0 to 9, but anything above 5 is way too slow for small gains: #76-100 -> 1 #51-76 -> 2 #etc level = max(1, min(5, (125 - speed) // 25)) kwargs["compress_level"] = level client_options["compress_level"] = level #default is good enough, no need to override, other options: #DEFAULT_STRATEGY, FILTERED, HUFFMAN_ONLY, RLE, FIXED #kwargs["compress_type"] = PIL.Image.DEFAULT_STRATEGY im.save(buf, "PNG", **kwargs) log("sending %sx%s %s as %s, mode=%s, options=%s", w, h, pixel_format, coding, im.mode, kwargs) data = buf.getvalue() buf.close() return coding, compression.Compressed( coding, data), client_options, image.get_width(), image.get_height(), 0, bpp
def PIL_encode(coding, image, quality, speed, supports_transparency): assert PIL is not None, "Python PIL is not available" pixel_format = image.get_pixel_format() w = image.get_width() h = image.get_height() rgb = { "XRGB" : "RGB", "BGRX" : "RGB", "RGBA" : "RGBA", "BGRA" : "RGBA", }.get(pixel_format, pixel_format) bpp = 32 #remove transparency if it cannot be handled: try: #PIL cannot use the memoryview directly: pixels = memoryview_to_bytes(image.get_pixels()) #it is safe to use frombuffer() here since the convert() #calls below will not convert and modify the data in place #and we save the compressed data then discard the image im = PIL.Image.frombuffer(rgb, (w, h), pixels, "raw", pixel_format, image.get_rowstride()) if coding.startswith("png") and not supports_transparency and rgb=="RGBA": im = im.convert("RGB") rgb = "RGB" bpp = 24 except Exception as e: log.error("PIL_encode(%s) converting to %s failed", (w, h, coding, "%s bytes" % image.get_size(), pixel_format, image.get_rowstride()), rgb, exc_info=True) raise e buf = StringIOClass() client_options = {} #only optimize with Pillow>=2.2 and when speed is zero if coding in ("jpeg", "webp"): q = int(min(99, max(1, quality))) kwargs = im.info kwargs["quality"] = q client_options["quality"] = q if coding=="jpeg" and PIL_can_optimize and speed<70: #(optimizing jpeg is pretty cheap and worth doing) kwargs["optimize"] = True client_options["optimize"] = True im.save(buf, coding.upper(), **kwargs) else: assert coding in ("png", "png/P", "png/L"), "unsupported png encoding: %s" % coding if coding in ("png/L", "png/P") and supports_transparency and rgb=="RGBA": #grab alpha channel (the last one): #we use the last channel because we know it is RGBA, #otherwise we should do: alpha_index= image.getbands().index('A') alpha = im.split()[-1] #convert to simple on or off mask: #set all pixel values below 128 to 255, and the rest to 0 def mask_value(a): if a<=128: return 255 return 0 mask = PIL.Image.eval(alpha, mask_value) else: #no transparency mask = None if coding=="png/L": im = im.convert("L", palette=PIL.Image.ADAPTIVE, colors=255) bpp = 8 elif coding=="png/P": #I wanted to use the "better" adaptive method, #but this does NOT work (produces a black image instead): #im.convert("P", palette=Image.ADAPTIVE) im = im.convert("P", palette=PIL.Image.WEB, colors=255) bpp = 8 if mask: # paste the alpha mask to the color of index 255 im.paste(255, mask) kwargs = im.info if mask is not None: client_options["transparency"] = 255 kwargs["transparency"] = 255 if PIL_can_optimize and speed==0: #optimizing png is very rarely worth doing kwargs["optimize"] = True client_options["optimize"] = True #level can range from 0 to 9, but anything above 5 is way too slow for small gains: #76-100 -> 1 #51-76 -> 2 #etc level = max(1, min(5, (125-speed)//25)) kwargs["compress_level"] = level client_options["compress_level"] = level #default is good enough, no need to override, other options: #DEFAULT_STRATEGY, FILTERED, HUFFMAN_ONLY, RLE, FIXED #kwargs["compress_type"] = PIL.Image.DEFAULT_STRATEGY im.save(buf, "PNG", **kwargs) log("sending %sx%s %s as %s, mode=%s, options=%s", w, h, pixel_format, coding, im.mode, kwargs) data = buf.getvalue() buf.close() return coding, compression.Compressed(coding, data), client_options, image.get_width(), image.get_height(), 0, bpp
#it is safe to use frombuffer() here since the convert() #calls below will not convert and modify the data in place #and we save the compressed data then discard the image pixels = image.get_pixels() if _memoryview and isinstance(pixels, _memoryview): #PIL cannot use the memoryview directly: pixels = pixels.tobytes() im = PIL.Image.frombuffer(rgb, (w, h), pixels, "raw", pixel_format, image.get_rowstride()) if coding.startswith("png") and not supports_transparency and rgb=="RGBA": im = im.convert("RGB") rgb = "RGB" bpp = 24 except Exception, e: log.error("PIL_encode(%s) converting to %s failed", (w, h, coding, "%s bytes" % image.get_size(), pixel_format, image.get_rowstride()), rgb, exc_info=True) raise e buf = StringIOClass() client_options = {} #only optimize with Pillow>=2.2 and when speed is zero if coding in ("jpeg", "webp"): q = int(min(99, max(1, quality))) kwargs = im.info kwargs["quality"] = q client_options["quality"] = q if coding=="jpeg" and PIL_can_optimize and speed<70: #(optimizing jpeg is pretty cheap and worth doing) kwargs["optimize"] = True client_options["optimize"] = True im.save(buf, coding.upper(), **kwargs) else: assert coding in ("png", "png/P", "png/L"), "unsupported png encoding: %s" % coding if coding in ("png/L", "png/P") and supports_transparency and rgb=="RGBA":