首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RTL窗口上的PrintWindow会生成带有PW_RENDERFULLCONTENT标志的镜像图像

RTL窗口上的PrintWindow会生成带有PW_RENDERFULLCONTENT标志的镜像图像
EN

Stack Overflow用户
提问于 2020-09-10 17:16:59
回答 1查看 513关注 0票数 2

我正在尝试使用以下python代码通过pywin32获取RTL窗口的图像:

代码语言:javascript
运行
复制
def get_window_image(hwnd: int, window_region: Region) -> np.ndarray:
    PW_RENDERFULLCONTENT = 2

    dc_handle = None
    dc_obj = None
    save_bitmap = None
    memory_dc_obj = None

    try:
        # Creating device context for retrieving the screenshot. Based on the following:
        # https://stackoverflow.com/questions/19695214/python-screenshot-of-inactive-window-printwindow-win32gui
        # Documentation about device context:
        # https://docs.microsoft.com/en-us/cpp/mfc/device-contexts?view=vs-2019

        dc_handle = win32gui.GetWindowDC(hwnd)
        dc_obj = win32ui.CreateDCFromHandle(dc_handle)
        memory_dc_obj = dc_obj.CreateCompatibleDC()

        # Create a bitmap from the device context
        save_bitmap = win32ui.CreateBitmap()
        save_bitmap.CreateCompatibleBitmap(dc_obj, window_region.get_width(), window_region.get_height())
        memory_dc_obj.SelectObject(save_bitmap)

        if sys.getwindowsversion().major >= 8:
            render_flags = PW_RENDERFULLCONTENT
        else:
            render_flags = 0

        # Take a screenshot of the window
        windll.user32.PrintWindow(hwnd, memory_dc_obj.GetSafeHdc(), render_flags)

        # Retrieve the bitmap content from the taken screenshot
        bmp_info = save_bitmap.GetInfo()
        bmp_str = save_bitmap.GetBitmapBits(True)

        bmp_height, bmp_width = bmp_info['bmHeight'], bmp_info['bmWidth']
        window_image = np.fromstring(string=bmp_str, dtype=np.uint8)

        window_image = window_image.reshape((bmp_height, bmp_width, 4))
        window_image[:, :, 3] = 255  # remove alpha channel

        return window_image

    finally:
        if save_bitmap is not None:
            win32gui.DeleteObject(save_bitmap.GetHandle())

        if memory_dc_obj is not None:
            memory_dc_obj.DeleteDC()

        if dc_obj is not None:
            dc_obj.DeleteDC()

        if dc_handle is not None:
            win32gui.ReleaseDC(hwnd, dc_handle)

生成RTL窗口的代码:

代码语言:javascript
运行
复制
win32gui.MessageBox(None, 'משהו בעברית', 'test-rtl', win32con.MB_ICONWARNING | win32con.MB_RTLREADING)

我向PrintWindow传递了标志- PW_RENDERFULLCONTENT = 2,它应该有助于用正确的边框而不是经典的边框来渲染窗口(也可以参见https://stackoverflow.com/a/40042587/4313487)

我有两台相同规格的电脑。在第一台PC上,图像被打印为镜像图像,在第二台PC上,它被打印为最初显示的图像。

这两台电脑都安装了Windows10,具有相同的区域和区域设置。在两台电脑上,messagebox窗口都有相同的样式标志,包括WS_EX_LAYOUTRTL。

来自PC1的图像-镜像:

来自PC2的图像(相同代码):

当传递给PrintWindow的标志为0(而不是PW_RENDERFULLCONTENT)时,镜像将在两台PC中镜像:

为什么会发生这种情况?

如何确保图像在不同的PC上以相同的方向打印?

EN

回答 1

Stack Overflow用户

发布于 2020-09-16 11:00:55

如果不推荐使用,则为

。打印窗口应用程序的最佳方式是什么,比如chromium,如果没有这个标志,应用程序就会呈现为黑屏?

我使用PrintWindow(没有PW_RENDERFULLCONTENT)打印chrome窗口,只要chrome窗口没有最小化,就没有黑屏问题。话虽如此,在过去很长一段时间内,Chrome返回黑屏都存在很多问题。

但是PrintWindow()并不能很好地工作。您可以从该DC中将GetWindowDC()BitBlt()尝试到您的位图中。或者GetClientRect()+ClientToScreen()BitBlt()从屏幕DC的矩形到您的位图。

或者看看Win10中添加的Screen Capture API。或者在Win8中添加的Desktop Duplication API。或者Direct3D。参见Ways to capture the screen

参考:Getting Black Screenshots with Windows API

因为您需要用python实现它,所以我建议您使用第一种方法(相对简单),即GetClientRect()+ClientToScreen() and BitBlt()...

代码示例:Capturing screenshots with win32api python returns black image

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63826570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档