Example #1
0
def missing_RANDR():
    if platform_is_osx():
        return False
    if not display:
        return False
    disp = display.Display()
    return not disp.has_extension("RANDR")
Example #2
0
def init():
    global refimgpath
    if not refimgpath:
        d = tempfile.mkdtemp(prefix="fillscreen")
        d = Path(d)
        atexit.register(d.rmtree)
        refimgpath = d / "ref.png"

        if not platform_is_win():  # TODO: win image viewer
            im = generate_image()
            im.save(refimgpath)
            cmd = [
                "pqiv",
                "--fullscreen",
                "--hide-info-box",
                "--disable-scaling",
                refimgpath,
            ]
            proc = EasyProcess(cmd).start()
            atexit.register(proc.stop)
            print(refimgpath)
            sleep(5)  # TODO: check image displayed
            if not proc.is_alive():
                raise FillscreenError("pqiv stopped: %s" % proc)

        # if the OS has color correction
        #  then the screenshot has slighly different color than the original image
        # TODO: color correction: linux? win?
        if platform_is_win() or platform_is_osx():
            refimgpath = refimgpath + ".pil.png"
            im = pyscreenshot.grab(backend="pil")
            im.save(refimgpath)
            log.debug("%s saved", refimgpath)

    return refimgpath
Example #3
0
    def grab(self, bbox=None):
        if platform_is_osx():
            raise WxBackendError("osx not supported")
        import wx

        global app
        if not app:
            app = wx.App()
        screen = wx.ScreenDC()
        size = screen.GetSize()
        if wx.__version__ >= "4":
            bmp = wx.Bitmap(size[0], size[1])
        else:
            bmp = wx.EmptyBitmap(size[0], size[1])
        mem = wx.MemoryDC(bmp)
        mem.Blit(0, 0, size[0], size[1], screen, 0, 0)
        del mem
        if hasattr(bmp, "ConvertToImage"):
            myWxImage = bmp.ConvertToImage()
        else:
            myWxImage = wx.ImageFromBitmap(bmp)
        im = Image.new("RGB", (myWxImage.GetWidth(), myWxImage.GetHeight()))
        if hasattr(Image, "frombytes"):
            # for Pillow
            im.frombytes(to_bytes(myWxImage.GetData()))
        else:
            # for PIL
            im.fromstring(myWxImage.GetData())
        if bbox:
            im = im.crop(bbox)
        return im
Example #4
0
def display_size():
    if platform_is_osx():
        from Quartz import CGDisplayBounds
        from Quartz import CGMainDisplayID

        mainMonitor = CGDisplayBounds(CGMainDisplayID())
        return int(mainMonitor.size.width), int(mainMonitor.size.height)

    if platform_is_win():
        from win32api import GetSystemMetrics

        return int(GetSystemMetrics(0)), int(GetSystemMetrics(1))

    if platform_is_linux():
        # http://www.cyberciti.biz/faq/how-do-i-find-out-screen-resolution-of-my-linux-desktop/
        # xdpyinfo  | grep 'dimensions:'
        screen_width, screen_height = 0, 0
        xdpyinfo = EasyProcess("xdpyinfo")
        xdpyinfo.enable_stdout_log = False
        if xdpyinfo.call().return_code != 0:
            raise ValueError("xdpyinfo error: %s" % xdpyinfo)
        for x in xdpyinfo.stdout.splitlines():
            if "dimensions:" in x:
                screen_width, screen_height = map(int, x.strip().split()[1].split("x"))

        return screen_width, screen_height
Example #5
0
def display_size():
    if platform_is_osx():
        return display_size_osx()

    if platform_is_win():
        return display_size_win()

    if platform_is_linux():
        return display_size_x()
Example #6
0
def backends(childprocess):
    # the order is based on performance
    if platform_is_linux():
        if use_x_display():
            if childprocess:
                yield ScrotWrapper
                yield PilWrapper
                yield MssWrapper
            else:
                yield PilWrapper
                yield MssWrapper
                yield ScrotWrapper
            yield MaimWrapper
            yield ImagemagickWrapper
            yield Gdk3PixbufWrapper
            yield WxScreen
            for x in qt():
                yield x
        yield GnomeDBusWrapper

        # on screen notification
        yield KwinDBusWrapper

        # flash effect
        yield GnomeScreenshotWrapper

        yield GrimWrapper

    elif platform_is_osx():
        # first check for X
        if use_x_display():
            pass
        else:
            # fast
            yield MssWrapper

            # latest version should work
            yield PilWrapper

            # alternatives for older pillow versions
            yield ScreencaptureWrapper
            yield MacQuartzWrapper

            # qt has some color difference

            # does not work: Gdk3, wx, Imagemagick

    elif platform_is_win():
        # fast
        yield MssWrapper

        yield PilWrapper
    else:
        for x in backend_dict.values():
            yield x
Example #7
0
    def grab(self, bbox=None):
        if platform_is_osx():
            raise ImagemagickBackendError("osx not supported")

        command = [PROGRAM, "-silent", "-window", "root"]
        if bbox:
            pbox = "{}x{}+{}+{}".format(bbox[2] - bbox[0], bbox[3] - bbox[1],
                                        bbox[0], bbox[1])
            command += ["-crop", pbox]
        im = read_prog_img(command)
        return im
Example #8
0
    def grab(self, bbox=None):
        if not platform_is_osx():
            raise ScreencaptureError("This backend runs only on Darwin")

        command = [PROGRAM, "-x"]
        if bbox:
            width = bbox[2] - bbox[0]
            height = bbox[3] - bbox[1]
            command += ["-R{},{},{},{}".format(bbox[0], bbox[1], width, height)]
        im = read_prog_img(command)
        return im
Example #9
0
    def grab(self, bbox=None):
        """Grabs an image directly to a buffer.

        :param bbox: Optional tuple or list containing (x1, y1, x2, y2) coordinates
            of sub-region to capture.
        :return: PIL RGB image
        :raises: ValueError, if image data does not have 3 channels (RGB), each with 8
            bits.
        :rtype: Image
        """
        if platform_is_osx():
            raise Gdk3BackendError("osx not supported")
        import gi

        gi.require_version("Gdk", "3.0")
        # gi.require_version('GdkPixbuf', '2.0')
        from gi.repository import Gdk
        from gi.repository import GdkPixbuf

        # read_pixel_bytes: New in version 2.32.
        if GdkPixbuf.PIXBUF_MAJOR == 2:
            if GdkPixbuf.PIXBUF_MINOR < 32:
                raise ValueError(
                    "GdkPixbuf min supported version: 2.32   current:"
                    + GdkPixbuf.PIXBUF_VERSION
                )

        w = Gdk.get_default_root_window()
        if bbox is not None:
            g = [bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]]
        else:
            g = w.get_geometry()
        pb = Gdk.pixbuf_get_from_window(w, *g)
        if not pb:
            raise Gdk3BackendError("empty buffer")

        if pb.get_bits_per_sample() != 8:
            raise Gdk3BackendError("Expected 8 bits per pixel.")
        elif pb.get_n_channels() != 3:
            raise Gdk3BackendError("Expected RGB image.")

        # Read the entire buffer into a python bytes object.
        # read_pixel_bytes: New in version 2.32.
        pixel_bytes = pb.read_pixel_bytes().get_data()  # type: bytes
        width, height = g[2], g[3]

        # Probably for SSE alignment reasons, the pixbuf has extra data in each line.
        # The args after "raw" help handle this; see
        # http://effbot.org/imagingbook/decoder.htm#the-raw-decoder
        return Image.frombytes(
            "RGB", (width, height), pixel_bytes, "raw", "RGB", pb.get_rowstride(), 1
        )
Example #10
0
    def grab(self, bbox=None):
        if platform_is_osx():
            raise ImagemagickBackendError("osx not supported")  # TODO

        # p = EasyProcess([PROGRAM, "-version"])
        # p.enable_stdout_log = False
        # p.enable_stderr_log = False
        # p.call()

        command = [PROGRAM, "-silent", "-window", "root"]
        if bbox:
            pbox = "{}x{}+{}+{}".format(bbox[2] - bbox[0], bbox[3] - bbox[1],
                                        bbox[0], bbox[1])
            command += ["-crop", pbox]
        im = read_prog_img(command)
        return im
Example #11
0
    def grab(self, bbox=None):
        if not platform_is_osx():
            raise ScreencaptureError("This backend runs only on Darwin")
        # p = EasyProcess([PROGRAM, "-help"])
        # p.enable_stdout_log = False
        # p.enable_stderr_log = False
        # p.call()

        command = [PROGRAM, "-x"]
        if bbox:
            width = bbox[2] - bbox[0]
            height = bbox[3] - bbox[1]
            command += [
                "-R{},{},{},{}".format(bbox[0], bbox[1], width, height)
            ]
        im = read_prog_img(command)
        return im
Example #12
0
def check_ref(backend, bbox, childprocess, refimgpath):
    img_ref = Image.open(refimgpath)
    logging.debug("ref full getextrema: %s", img_ref.getextrema())
    if bbox:
        img_ref = img_ref.crop(bbox)

    im = pyscreenshot.grab(bbox=bbox,
                           backend=backend,
                           childprocess=childprocess)

    img_ref = img_ref.convert("RGB")
    logging.debug("ref  getextrema: %s", img_ref.getextrema())
    im = im.convert("RGB")
    logging.debug("shot getextrema: %s", im.getextrema())

    eq_("RGB", img_ref.mode)
    eq_("RGB", im.mode)

    img_debug(img_ref, "ref" + str(bbox))
    img_debug(im, str(backend) + str(bbox))

    img_diff = ImageChops.difference(img_ref, im)
    ex = img_diff.getextrema()
    logging.debug("diff getextrema: %s", ex)
    diff_bbox = img_diff.getbbox()
    if diff_bbox:
        img_debug(img_diff, "img_diff" + str(diff_bbox))
    if (platform_is_osx() and backend
            and backend in ["qtpy", "pyqt", "pyqt5", "pyside", "pyside2"]):
        # TODO: qt color problem on osx
        color_diff_max = max([b for (_, b) in ex])
        ok_(color_diff_max < 70)
    else:
        eq_(
            diff_bbox,
            None,
            "different image data %s bbox=%s extrema:%s diff_bbox=%s" %
            (backend, bbox, ex, diff_bbox),
        )
Example #13
0
def init():
    global refimgpath
    if not refimgpath:
        d = tempfile.mkdtemp(prefix="fillscreen")
        atexit.register(lambda: rmtree(d))
        refimgpath = join(d, "ref.png")

        im = generate_image()
        im.save(refimgpath)

        if platform_is_win():
            cmd = [
                "C:\\Program Files (x86)\\FastStone Image Viewer\\FSViewer.exe",
                refimgpath,
            ]
        else:
            cmd = [
                "pqiv",
                "--fullscreen",
                "--hide-info-box",
                "--disable-scaling",
                refimgpath,
            ]
        proc = EasyProcess(cmd).start()
        atexit.register(proc.stop)
        print(refimgpath)
        sleep(5)  # wait for image displayed
        if not proc.is_alive():
            raise FillscreenError("pqiv stopped: %s" % proc)

        # if the OS has color correction
        #  then the screenshot has slighly different color than the original image
        if platform_is_win() or platform_is_osx():
            refimgpath = refimgpath + ".pil.png"
            im = pyscreenshot.grab(backend="pil")
            im.save(refimgpath)
            log.debug("%s saved", refimgpath)

    return refimgpath
Example #14
0
from pyscreenshot.util import platform_is_osx
from bt import backend_to_check, check_import

# qt color problem on osx
if not platform_is_osx():

    if check_import("PySide"):

        def test_pyside():
            backend_to_check("pyside")
Example #15
0
try:
    from Xlib import display
except ImportError:
    display = None

# https://github.com/python-xlib/python-xlib/blob/master/examples/xrandr.py#L44
def missing_RANDR():
    if display:
        return False
    disp = display.Display()
    return not disp.has_extension("RANDR")


ok = False
if not six.PY2 and check_import("mss"):
    if platform_is_osx() and not use_x_display():
        ok = True
    if platform_is_linux() and use_x_display():
        ok = True
    if platform_is_win():
        ok = True

if ok:

    def test_mss():
        if missing_RANDR():
            try:
                backend_to_check("mss")
            except FailedBackendError:
                pass
        else:
from bt import backend_to_check
from pyscreenshot.util import platform_is_osx

if platform_is_osx():

    def test_mac_screencapture():
        backend_to_check("mac_screencapture")
Example #17
0
from bt import backend_to_check, check_import
from pyscreenshot.util import platform_is_osx

if not platform_is_osx() and check_import("wx"):

    def test_wx():
        backend_to_check("wx")