Example #1
0
def rgb_to_bitmap(rgb_data, bytes_per_pixel: int, w: int, h: int):
    log("rgb_to_bitmap%s", (rgb_data, bytes_per_pixel, w, h))
    assert bytes_per_pixel in (3, 4)  #only BGRA or BGR are supported
    assert w > 0 and h > 0
    header = BITMAPV5HEADER()
    header.bV5Size = sizeof(BITMAPV5HEADER)
    header.bV5Width = w
    header.bV5Height = -h
    header.bV5Planes = 1
    header.bV5BitCount = bytes_per_pixel * 8
    header.bV5Compression = BI_RGB  #BI_BITFIELDS
    #header.bV5RedMask = 0x000000ff
    #header.bV5GreenMask = 0x0000ff00
    #header.bV5BlueMask = 0x00ff0000
    #header.bV5AlphaMask = 0xff000000
    bitmap = 0
    try:
        hdc = GetDC(None)
        dataptr = c_void_p()
        log("GetDC()=%#x", hdc)
        bitmap = CreateDIBSection(hdc, byref(header), win32con.DIB_RGB_COLORS,
                                  byref(dataptr), None, 0)
    finally:
        ReleaseDC(None, hdc)
    if not dataptr or not bitmap:
        raise ctypes.WinError(ctypes.get_last_error())
    log("CreateDIBSection(..) got bitmap=%#x, dataptr=%s", int(bitmap),
        dataptr)
    img_data = create_string_buffer(rgb_data)
    ctypes.memmove(dataptr, byref(img_data), w * h * bytes_per_pixel)
    return bitmap
Example #2
0
def rgba_to_bitmap(rgba, w, h):
    header = BITMAPV5HEADER()
    header.bV5Size = sizeof(BITMAPV5HEADER)
    header.bV5Width = w
    header.bV5Height = -h
    header.bV5Planes = 1
    header.bV5BitCount = 32
    header.bV5Compression = BI_RGB  #BI_BITFIELDS
    #header.bV5RedMask = 0x000000ff
    #header.bV5GreenMask = 0x0000ff00
    #header.bV5BlueMask = 0x00ff0000
    #header.bV5AlphaMask = 0xff000000
    bitmap = 0
    try:
        hdc = GetDC(None)
        dataptr = c_void_p()
        log("GetDC()=%#x", hdc)
        bitmap = CreateDIBSection(hdc, byref(header), win32con.DIB_RGB_COLORS,
                                  byref(dataptr), None, 0)
    finally:
        ReleaseDC(None, hdc)
    assert dataptr and bitmap, "failed to create DIB section"
    log("CreateDIBSection(..) got bitmap=%#x, dataptr=%s", int(bitmap),
        dataptr)
    img_data = create_string_buffer(rgba)
    ctypes.memmove(dataptr, byref(img_data), w * 4 * h)
    return bitmap
Example #3
0
def get_desktop_bit_depth():
    desktop_wnd = GetDesktopWindow()
    dc = GetWindowDC(desktop_wnd)
    assert dc, "failed to get a drawing context from the desktop window %s" % desktop_wnd
    bit_depth = GetDeviceCaps(dc, win32con.BITSPIXEL)
    log("get_desktop_bit_depth()=%i", bit_depth)
    ReleaseDC(desktop_wnd, dc)
    return bit_depth
Example #4
0
def _get_device_caps(constant):
    dc = None
    try:
        dc = GetDC(None)
        return GetDeviceCaps(dc, constant)
    finally:
        if dc:
            ReleaseDC(None, dc)
Example #5
0
    def set_clipboard_image(self, img_format, img_data):
        image_formats = {}
        if COMPRESSED_IMAGES:
            #first save it as binary compressed data:
            fmt_name = LPCSTR(img_format.upper().encode("latin1")+b"\0")   #ie: "PNG"
            fmt = RegisterClipboardFormatA(fmt_name)
            if fmt:
                buf = create_string_buffer(img_data)
                pbuf = cast(byref(buf), c_void_p)
                l = len(img_data)
                data_handle = GlobalAlloc(GMEM_MOVEABLE, l)
                if not data_handle:
                    log.error("Error: failed to allocate %i bytes of global memory", l)
                    return True
                data = GlobalLock(data_handle)
                if not data:
                    log("failed to lock data handle %#x (may try again)", data_handle)
                    return False
                log("got data handle lock %#x for %i bytes of '%s' data", data, l, img_format)
                try:
                    memmove(data, pbuf, l)
                finally:
                    GlobalUnlock(data)
                image_formats[fmt] = data_handle

        #also convert it to a bitmap:
        from PIL import Image
        buf = BytesIO(img_data)
        img = Image.open(buf)
        if img.mode!="RGBA":
            img = img.convert("RGBA")
        rgb_data = img.tobytes("raw", "BGRA")
        w, h = img.size
        log("set_clipboard_image(%s, %s) image size=%s, BGR buffer=%i bytes",
            img_format, ellipsizer(data), img.size, len(rgb_data))
        header = BITMAPINFOHEADER()
        memset(byref(header), 0, sizeof(BITMAPINFOHEADER ))
        header.biSize       = sizeof(BITMAPINFOHEADER)
        header.biWidth      = w
        header.biHeight     = -h
        header.biPlanes     = 1
        header.biBitCount   = 32
        header.biCompression    = BI_RGB
        header.biSizeImage      = 0
        header.biXPelsPerMeter  = 10
        header.biYPelsPerMeter  = 10
        bitmapinfo = BITMAPINFO()
        bitmapinfo.bmiColors = 0
        memmove(byref(bitmapinfo.bmiHeader), byref(header), sizeof(BITMAPINFOHEADER))
        rgb_buf = create_string_buffer(rgb_data)
        pbuf = cast(byref(rgb_buf), c_void_p)
        hdc = GetDC(None)
        CBM_INIT = 4
        bitmap = CreateDIBitmap(hdc, byref(header), CBM_INIT, pbuf, byref(bitmapinfo), win32con.DIB_RGB_COLORS)
        ReleaseDC(None, hdc)
        image_formats[win32con.CF_BITMAP] = bitmap

        self.do_set_clipboard_image(image_formats)
Example #6
0
 def clean_dc(self):
     dc = self.dc
     wnd = self.wnd
     if dc and wnd:
         self.dc = None
         self.wnd = None
         ReleaseDC(wnd, dc)
     memdc = self.memdc
     if memdc:
         self.memdc = None
         DeleteDC(memdc)
Example #7
0
 def cleanup(self):
     if self.disabled_dwm_composition:
         set_dwm_composition(DWM_EC_ENABLECOMPOSITION)
     dc = self.dc
     if dc:
         self.dc = None
         ReleaseDC(dc)
     memdc = self.memdc
     if memdc:
         self.memdc = None
         DeleteDC(memdc)
Example #8
0
 def clean(self):
     if self.disabled_dwm_composition:
         set_dwm_composition(DWM_EC_ENABLECOMPOSITION)
     dc = self.dc
     wnd = self.wnd
     if dc and wnd:
         self.dc = None
         self.wnd = None
         ReleaseDC(wnd, dc)
     memdc = self.memdc
     if memdc:
         self.memdc = None
         DeleteDC(memdc)
Example #9
0
def get_cursor_data(hCursor):
    #w, h = get_fixed_cursor_size()
    if not hCursor:
        return None
    x, y = 0, 0
    dc = None
    memdc = None
    bitmap = None
    old_handle = None
    pixels = None
    try:
        ii = ICONINFO()
        ii.cbSize = sizeof(ICONINFO)
        if not GetIconInfo(hCursor, byref(ii)):
            raise WindowsError()  #@UndefinedVariable
        x = ii.xHotspot
        y = ii.yHotspot
        cursorlog(
            "get_cursor_data(%#x) hotspot at %ix%i, hbmColor=%#x, hbmMask=%#x",
            hCursor, x, y, ii.hbmColor or 0, ii.hbmMask or 0)
        if not ii.hbmColor:
            #FIXME: we don't handle black and white cursors
            return None
        iie = ICONINFOEXW()
        iie.cbSize = sizeof(ICONINFOEXW)
        if not GetIconInfoExW(hCursor, byref(iie)):
            raise WindowsError()  #@UndefinedVariable
        name = iie.szResName[:MAX_PATH]
        cursorlog("wResID=%#x, sxModName=%s, szResName=%s", iie.wResID,
                  iie.sxModName[:MAX_PATH], name)
        bm = Bitmap()
        if not GetObjectA(ii.hbmColor, sizeof(Bitmap), byref(bm)):
            raise WindowsError()  #@UndefinedVariable
        cursorlog(
            "cursor bitmap: type=%i, width=%i, height=%i, width bytes=%i, planes=%i, bits pixel=%i, bits=%#x",
            bm.bmType, bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, bm.bmPlanes,
            bm.bmBitsPixel, bm.bmBits or 0)
        w = bm.bmWidth
        h = bm.bmHeight
        dc = GetDC(None)
        assert dc, "failed to get a drawing context"
        memdc = CreateCompatibleDC(dc)
        assert memdc, "failed to get a compatible drawing context from %s" % dc
        bitmap = CreateCompatibleBitmap(dc, w, h)
        assert bitmap, "failed to get a compatible bitmap from %s" % dc
        old_handle = SelectObject(memdc, bitmap)

        #check if icon is animated:
        UINT_MAX = 2**32 - 1
        if not DrawIconEx(memdc, 0, 0, hCursor, w, h, UINT_MAX, 0, 0):
            cursorlog("cursor is animated!")

        #if not DrawIcon(memdc, 0, 0, hCursor):
        if not DrawIconEx(memdc, 0, 0, hCursor, w, h, 0, 0,
                          win32con.DI_NORMAL):
            raise WindowsError()  #@UndefinedVariable

        buf_size = bm.bmWidthBytes * h
        buf = create_string_buffer(b"", buf_size)
        r = GetBitmapBits(bitmap, buf_size, byref(buf))
        cursorlog("get_cursor_data(%#x) GetBitmapBits(%#x, %#x, %#x)=%i",
                  hCursor, bitmap, buf_size, addressof(buf), r)
        if not r:
            cursorlog.error("Error: failed to copy screen bitmap data")
            return None
        elif r != buf_size:
            cursorlog.warn(
                "Warning: invalid cursor buffer size, got %i bytes but expected %i",
                r, buf_size)
            return None
        else:
            #32-bit data:
            pixels = bytearray(strtobytes(buf.raw))
            has_alpha = False
            has_pixels = False
            for i in range(len(pixels) // 4):
                has_pixels = has_pixels or pixels[i * 4] != 0 or pixels[
                    i * 4 + 1] != 0 or pixels[i * 4 + 2] != 0
                has_alpha = has_alpha or pixels[i * 4 + 3] != 0
                if has_pixels and has_alpha:
                    break
            if has_pixels and not has_alpha:
                #generate missing alpha - don't ask me why
                for i in range(len(pixels) // 4):
                    if pixels[i * 4] != 0 or pixels[i * 4 +
                                                    1] != 0 or pixels[i * 4 +
                                                                      2] != 0:
                        pixels[i * 4 + 3] = 0xff
        return [0, 0, w, h, x, y, hCursor, bytes(pixels), strtobytes(name)]
    except Exception as e:
        cursorlog("get_cursor_data(%#x)", hCursor, exc_info=True)
        cursorlog.error("Error: failed to grab cursor:")
        cursorlog.error(" %s", str(e) or type(e))
        return None
    finally:
        if old_handle:
            SelectObject(memdc, old_handle)
        if bitmap:
            DeleteObject(bitmap)
        if memdc:
            DeleteDC(memdc)
        if dc:
            ReleaseDC(None, dc)