Ejemplo n.º 1
0
    def windowshots(self, x1, y1, x2, y2):
        w, h = x2 - x1, y2 - y1
        # wDC = GetDC(hwnd)
        # 根据窗口句柄获取窗口的设备上下文DC(Divice Context)
        # 获取桌面
        hdesktop = GetDesktopWindow()
        wDC = GetWindowDC(hdesktop)
        # 根据窗口的DC获取dcObj
        dcObj = CreateDCFromHandle(wDC)
        # dcObj创建可兼容的DC
        cDC = dcObj.CreateCompatibleDC()
        # 创建bigmap准备保存图片
        dataBitMap = CreateBitmap()
        # 为bitmap开辟空间
        dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
        # 高度cDC,将截图保存到dataBitMap中
        cDC.SelectObject(dataBitMap)
        # 截取从左上角(0,0)长宽为(w,h)的图片
        cDC.BitBlt((0, 0), (w, h), dcObj, (x1, y1), SRCCOPY)
        # 保存图像
        # dataBitMap.SaveBitmapFile(cDC, 'test.jpg')
        signedIntsArray = dataBitMap.GetBitmapBits(True)
        # Free Resources
        # 释放资源
        DeleteObject(dataBitMap.GetHandle())
        cDC.DeleteDC()
        dcObj.DeleteDC()
        ReleaseDC(hdesktop, wDC)

        screen = np.frombuffer(signedIntsArray, dtype='uint8')
        screen.shape = (h, w, 4)
        screen = cv2.cvtColor(screen, cv2.COLOR_BGRA2BGR)
        return screen
Ejemplo n.º 2
0
def icon_path(exe: path_type, name: str):
    id_file_name = f'{name}.png'
    id_path = p_join(this_dir, 'icons', id_file_name)

    if not p_exists(id_path):

        ico_x = GetSystemMetrics(SM_CXICON)

        try:
            large, small = ExtractIconEx(exe, 0)
        except error:
            return default_icon_path

        if not len(large):
            return default_icon_path

        if len(small):
            DestroyIcon(small[0])

        hdc = CreateDCFromHandle(GetDC(0))
        h_bmp = CreateBitmap()
        h_bmp.CreateCompatibleBitmap(hdc, ico_x, ico_x)
        hdc = hdc.CreateCompatibleDC()

        hdc.SelectObject(h_bmp)
        hdc.DrawIcon((0, 0), large[0])

        bmp_str = h_bmp.GetBitmapBits(True)
        img = Image.frombuffer('RGBA', (32, 32), bmp_str, 'raw', 'BGRA', 0, 1)

        img.save(id_path)

        print(f'Icon of {exe} saved in {id_path}')

    return id_path
def save_screenshot():
    hwnd = GetDesktopWindow()
    width = GetSystemMetrics(SM_CXVIRTUALSCREEN)
    height = GetSystemMetrics(SM_CYVIRTUALSCREEN)
    x = GetSystemMetrics(SM_XVIRTUALSCREEN)
    y = GetSystemMetrics(SM_YVIRTUALSCREEN)

    hwnd_dc = GetWindowDC(hwnd)
    mfc_dc = CreateDCFromHandle(hwnd_dc)
    save_dc = mfc_dc.CreateCompatibleDC()

    save_bit_map = CreateBitmap()
    save_bit_map.CreateCompatibleBitmap(mfc_dc, width, height)
    save_dc.SelectObject(save_bit_map)
    save_dc.BitBlt((0, 0), (width, height), mfc_dc, (x, y), SRCCOPY)

    bmp_info = save_bit_map.GetInfo()
    bmp_str = save_bit_map.GetBitmapBits(True)
    image = Image.frombuffer('RGB',
                             (bmp_info['bmWidth'], bmp_info['bmHeight']),
                             bmp_str, 'raw', 'BGRX', 0, 1)
    time_str = str(ctime()).replace(' ', '_').replace(':', '_').lower()
    name_scr = 'screen_' + time_str + '.png'
    image.save(name_scr, format='png')
    log_record('сохранен скриншот: ' + name_scr)
    save_dc.DeleteDC()
    DeleteObject(save_bit_map.GetHandle())
Ejemplo n.º 4
0
 def Screenshot(self):
     ########################
     # Usadas en Screenshot #
     ########################
     from time import sleep
     from win32gui import GetDesktopWindow, GetWindowDC
     from win32ui import CreateDCFromHandle, CreateBitmap
     from win32con import SRCCOPY, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN
     from win32api import GetSystemMetrics, GetUserName
     from time import strftime
     print "Tomando Pantallazo"
     # Toma 4 pantallazos
     # Cada pantallazo lo llama pantallazo1 , 2 ,3 o 4
     # Lo hace cada 2 segundos
     t = strftime("%Y-%H%M%S")
     hwin = GetDesktopWindow()
     width = GetSystemMetrics(SM_CXVIRTUALSCREEN)
     height = GetSystemMetrics(SM_CYVIRTUALSCREEN)
     left = GetSystemMetrics(SM_XVIRTUALSCREEN)
     top = GetSystemMetrics(SM_YVIRTUALSCREEN)
     hwindc = GetWindowDC(hwin)
     srcdc = CreateDCFromHandle(hwindc)
     memdc = srcdc.CreateCompatibleDC()
     bmp = CreateBitmap()
     bmp.CreateCompatibleBitmap(srcdc, width, height)
     memdc.SelectObject(bmp)
     memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), SRCCOPY)
     bmp.SaveBitmapFile(
         memdc, "C:\\Users\\" + GetUserName() +
         "\\Downloads\\test\\screen" + t + ".bmp")
Ejemplo n.º 5
0
def screenshot(**kwargs):
    global client

    dimensions = GetWindowDC(client)
    handle = CreateDCFromHandle(dimensions)
    buff = handle.CreateCompatibleDC()

    screenshot = CreateBitmap()
    screenshot.CreateCompatibleBitmap(handle, kwargs['width'],
                                      kwargs['height'])

    buff.SelectObject(screenshot)
    buff.BitBlt((0, 0), (kwargs['width'], kwargs['height']), handle,
                (kwargs['left'], kwargs['top']), SRCCOPY)

    pixels = screenshot.GetBitmapBits(True)
    im = array(
        Image.frombuffer('RGB', (kwargs['width'], kwargs['height']), pixels,
                         'raw', 'BGRX', 0, 1))

    if kwargs['cleaning'] == True:
        im = cleaning(kwargs['width'], kwargs['height'], im)

    handle.DeleteDC()
    buff.DeleteDC()
    ReleaseDC(client, dimensions)
    DeleteObject(screenshot.GetHandle())
    return im
Ejemplo n.º 6
0
    def hwd_screenshot(self):
        # 获取句柄窗口的大小信息
        try:
            _left, _top, _right, _bot = self.get_window_rect()
            _width = _right - _left
            _height = _bot - _top
            # 返回句柄窗口的设备环境,覆盖整个窗口,包括非客户区,标题栏,菜单,边框
            _hwnd_dc = GetWindowDC(self.hwnd)
            # 创建设备描述表
            _mfc_dc = CreateDCFromHandle(_hwnd_dc)
            # 创建内存设备描述表
            _save_dc = _mfc_dc.CreateCompatibleDC()
            # 创建位图对象准备保存图片
            _save_bit_map = CreateBitmap()
            # 为bitmap开辟存储空间
            _save_bit_map.CreateCompatibleBitmap(_mfc_dc, _width, _height)
            # 将截图保存到saveBitMap中
            _save_dc.SelectObject(_save_bit_map)
            # 保存bitmap到内存设备描述表
            _save_dc.BitBlt((0, 0), (_width, _height), _mfc_dc, (0, 0),
                            win32con.SRCCOPY)

            # 如果要截图到打印设备:
            ###最后一个int参数:0-保存整个窗口,1-只保存客户区。如果PrintWindow成功函数返回值为1
            # result = windll.user32.PrintWindow(hWnd,_save_dc.GetSafeHdc(),0)
            # print(result) #PrintWindow成功则输出1

            # 保存图像
            ##方法一:windows api保存
            ###保存bitmap到文件
            # _save_bit_map.SaveBitmapFile(_save_dc, "img_Winapi.bmp")

            ##方法二(第一部分):PIL保存
            ###获取位图信息
            # bmpinfo = _save_bit_map.GetInfo()
            # bmpstr = _save_bit_map.GetBitmapBits(True)
            ###生成图像
            # im_PIL = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)
            ##方法二(后续转第二部分)

            ##方法三(第一部分):opencv+numpy保存
            ###获取位图信息
            signed_ints_array = _save_bit_map.GetBitmapBits(True)
            return Image.get_img_opencv(signed_ints_array, _width, _height)
            ##方法三(后续转第二部分)
        finally:
            # 内存释放
            DeleteObject(_save_bit_map.GetHandle())
            _save_dc.DeleteDC()
            _mfc_dc.DeleteDC()
            ReleaseDC(self.hwnd, _hwnd_dc)
Ejemplo n.º 7
0
    def _capture(self):
        # make sure the process is DPI aware, otherwise the image
        # is only a part of the full monitor content
        # (necessary only on Win 8.1+)
        old_awareness = self._dpi_aware()
        self._set_dpi_aware(True)

        # get width and height of current monitor
        width = GetSystemMetrics(SM_CXVIRTUALSCREEN)
        height = GetSystemMetrics(SM_CYVIRTUALSCREEN)

        # get 'desktop' window handle
        handle_desktop = GetDesktopWindow()

        # get window graphic context handle
        handle_context = GetWindowDC(handle_desktop)

        # create device context
        dev_ctx = CreateDCFromHandle(handle_context)

        # create destination for original device context
        dest_ctx = dev_ctx.CreateCompatibleDC()

        # create bitmap compatible with desktop window device
        bmp = CreateBitmap()
        bmp.CreateCompatibleBitmap(dev_ctx, width, height)

        # select bitmap into destination device
        dest_ctx.SelectObject(bmp)

        # populate selected bitmap in destination device
        dest_ctx.BitBlt(
            (0, 0),  # start point (x, y)
            (width, height),  # size of rectangle
            dev_ctx,
            (  # source device
                GetSystemMetrics(SM_XVIRTUALSCREEN),
                GetSystemMetrics(SM_YVIRTUALSCREEN)
            ),  # source rectangle, can be different monitor
            SRCCOPY  # copy directly without filters
        )

        # save bitmap to file
        bmp.SaveBitmapFile(dest_ctx, self.file_path)

        # return to the original state
        self._set_dpi_aware(old_awareness)
Ejemplo n.º 8
0
def getBmp(box=None, handle=None, dcTuple=None):

    if handle is None:
        handle = getHandle()
    if dcTuple is None:
        localDC = True
        dcTuple = getDc(handle)
    else:
        localDC = False

    left, up, right, down = box if box else wgui.GetWindowRect(handle)
    height, width = down - up, right - left
    size = width, height
    bmp = CreateBitmap()
    bmp.CreateCompatibleBitmap(dcTuple[1], width, height)
    dcTuple[2].SelectObject(bmp)
    dcTuple[2].BitBlt((0, 0), size, dcTuple[1], (left, up), win32con.SRCCOPY)
    if localDC:
        dropDc(handle, dcTuple)
    return bmp
Ejemplo n.º 9
0
 def ScreenShot(self):
     """
     截图 网上找的代码直接复制修改的
     后面加了释放资源代码,网上找的
     """
     hwndDC = GetWindowDC(self.mHwnd)
     mfcDC = CreateDCFromHandle(hwndDC)
     saveDC = mfcDC.CreateCompatibleDC()
     saveBitMap = CreateBitmap()
     saveBitMap.CreateCompatibleBitmap(mfcDC, self.mWindowWidth,
                                       self.mWindowHeight)
     saveDC.SelectObject(saveBitMap)
     saveDC.BitBlt((0, 0), (self.mWindowWidth, self.mWindowHeight), mfcDC,
                   (0, 0), SRCCOPY)
     saveBitMap.SaveBitmapFile(saveDC, self.mScreenShotFileName)
     self.mImageSrc = aircv.imread(self.mScreenShotFileName)
     # release
     DeleteObject(saveBitMap.GetHandle())
     mfcDC.DeleteDC()
     saveDC.DeleteDC()
     ReleaseDC(self.mHwnd, hwndDC)
Ejemplo n.º 10
0
def get_screenshot():
    hdesktop = GetDesktopWindow()

    width = GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
    height = GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
    left = GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
    top = GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)

    hdc = GetWindowDC(hdesktop)
    source_dc = CreateDCFromHandle(hdc)
    target_dc = source_dc.CreateCompatibleDC()

    bmp = CreateBitmap()
    bmp.CreateCompatibleBitmap(source_dc, width, height)

    target_dc.SelectObject(bmp)
    target_dc.BitBlt((0, 0), (width, height), source_dc, (left, top),
                     win32con.SRCCOPY)

    tmp = tempfile.NamedTemporaryFile(suffix='.bmp')
    bmp.SaveBitmapFile(target_dc, tmp.name)
    return tmp
Ejemplo n.º 11
0
    def __getIconFromProc(self, proc):

        path = proc.cmdline()[0]

        ico_size = GetSystemMetrics(SM_CXICON)

        large, _ = ExtractIconEx(path, 0)

        hdc = CreateDCFromHandle(GetDC(0))
        hbmp = CreateBitmap()
        hbmp.CreateCompatibleBitmap(hdc, ico_size, ico_size)
        hdc = hdc.CreateCompatibleDC()

        hdc.SelectObject(hbmp)
        hdc.DrawIcon((0, 0), large[0])

        bmpstr = hbmp.GetBitmapBits(True)

        image = Image.frombuffer('RGB', (ico_size, ico_size), bmpstr, 'raw',
                                 'BGRX', 0, 1)

        self.__imageList.append(image)
class SoullessEnv(gym.Env):
    metadata = {'render.modes': ['human']}
    user32 = WinDLL("user32")
    DEATHCOUNT_PATTERN = re.compile("(\d+)")
    KEYS = (KEYS.LEFT, KEYS.RIGHT, KEYS.DELETE)
    TRANSITION_TO_ACTION = {"10": "UP", "01": "DOWN", "00": False, "11": False}

    def __init__(self):
        self.AHK = AHK()
        self.application = self.start_game()
        self.process_id = self.application.process
        self.process = Process(pid=self.process_id)
        self.dialog = self.get_window_dialog()
        self.handle = self.dialog.handle
        self.window = Window.from_pid(self.AHK, self.process_id)

        left, top, right, bot = GetClientRect(self.handle)
        w = right - left
        h = bot - top

        self.hwndDC = GetWindowDC(self.handle)
        self.mfcDC = CreateDCFromHandle(self.hwndDC)
        self.saveDC = self.mfcDC.CreateCompatibleDC()
        self.saveDC_handle = self.saveDC.GetSafeHdc()

        self.saveBitMap = CreateBitmap()
        self.saveBitMap.CreateCompatibleBitmap(self.mfcDC, w, h)
        self.bmpinfo = self.saveBitMap.GetInfo()
        self.saveDC.SelectObject(self.saveBitMap)

        self.navigate_main_menu()
        self.enter_avoidance()
        self.process.suspend()

        self.PREVIOUS_ACTION = 0
        self.deathcount = self.get_game_deathcount()
        self.action_space = spaces.Discrete(6)
        self.elapsed_time = 0.0

        self.observation_space = spaces.Dict({"window":
                                                  spaces.Box(low=0, high=255, shape=self.get_observation_space_size(),
                                                             dtype=np.uint8),
                                              "time": spaces.Box(low=0, high=900, shape=(1,))})

    def start_game(self):
        """starts the Soulless process"""
        app = Application().start(
            "D:/Users/david/PycharmProjects/reinforcement-learning/gym-soulless/Soulless 1.3HM/Soulless Hard Mode.exe")
        return app

    def get_window_dialog(self):
        """:returns the main dialog of the application, which is the entry-point for interacting with it"""
        return self._top_window()

    @try_loop(error_type=RuntimeError)
    def _top_window(self):
        return self.application.top_window()

    def navigate_main_menu(self):
        """from the title screen it navigates the menus until it enters the game"""
        self.window.send("{Shift}", blocking=False)
        sleep(3)
        self.window.send("{Shift}", blocking=False)

    def enter_avoidance(self):
        self.window.send("{Left down}", blocking=False)
        sleep(0.3)
        self.window.send("{Left up}", blocking=False)
        sleep(2)

    def capture_window(self):
        """:returns a np array image of the dialog cropped to exclude the margins for resizing the window
        https://stackoverflow.com/questions/19695214/python-screenshot-of-inactive-window-printwindow-win32gui"""

        SoullessEnv.user32.PrintWindow(HWND(self.handle), self.saveDC_handle, 3)
        bmpstr = self.saveBitMap.GetBitmapBits(True)

        im = Image.frombuffer(
            'RGB',
            (self.bmpinfo['bmWidth'], self.bmpinfo['bmHeight']),
            bmpstr, 'raw', 'BGRX', 0, 1)
        return np.array(im, copy=False)

    def step(self, action: int):
        """expects the game to be in a suspended state"""
        is_done, obs, reward = self.step_and_track_elapsed_time(action)
        obs = {"window": obs, "time": np.array([self.elapsed_time], dtype=np.float)}
        return obs, reward, is_done, {}

    def step_and_track_elapsed_time(self, action):
        self.process.resume()
        step_start_time = perf_counter()
        is_done, obs = self._step(action)
        self.process.suspend()
        step_end_time = perf_counter()
        elapsed_time = step_end_time - step_start_time
        self.elapsed_time += elapsed_time
        return is_done, obs, elapsed_time

    def _step(self, action):
        self.perform_action(action)
        obs = self.capture_window()
        is_done = self.is_done()
        if is_done:
            self.update_env_deathcount()
        return is_done, obs

    def perform_action(self, action):
        keystrokes = self.get_action_transition(self.PREVIOUS_ACTION, action)
        self.send_input_to_game(keystrokes)
        self.PREVIOUS_ACTION = action

    def is_done(self):
        return self.get_game_deathcount() > self.deathcount

    def update_env_deathcount(self):
        self.deathcount = self.get_game_deathcount()

    def get_action_transition(self, old_action: int, new_action: int):
        """:param old_action is the action performed on the previous step, or no-op if this is the first step
        :param new_action is the action performed on this step
        :returns the input to the send function needed to transition from the old action to the new action"""

        old_action, new_action = bin(old_action)[2:].zfill(3), bin(new_action)[2:].zfill(3)
        actions = map(SoullessEnv.TRANSITION_TO_ACTION.get, map("".join, zip(old_action, new_action)))

        return "".join(getattr(key, action) for key, action in zip(SoullessEnv.KEYS, actions) if action)

    def send_input_to_game(self, keystrokes: str):
        """:param keystrokes is the input to the send_keys function"""
        self.window.send(keystrokes, blocking=False)

    def reset(self):
        self.process.resume()
        self.window.send("r", delay=150)
        self.process.suspend()
        self.elapsed_time = 0.0

        return {"window": self.capture_window(), "time": np.array([self.elapsed_time], dtype=np.float)}

    def render(self, mode='human'):
        pass

    def close(self):
        DeleteObject(self.saveBitMap.GetHandle())
        self.saveDC.DeleteDC()
        self.mfcDC.DeleteDC()
        ReleaseDC(self.handle, self.hwndDC)
        self.application.kill()

    def get_observation_space_size(self):
        return self.capture_window().shape

    def get_game_deathcount(self):
        """:returns the number of times the kid has died"""
        title = self.window.title.decode("utf8")
        return int(re.search(SoullessEnv.DEATHCOUNT_PATTERN, title)[0])