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

如何解决RTL窗口上的PrintWindow生成带有PW_RENDERFULLCONTENT标志的镜像图像

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

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窗口的代码:

win32gui.MessageBox(None,'משהו בעברית','test-rtl',win32con.MB_ICONWARNING | win32con.MB_RTLREADING)

我正在传递PrintWindow标志-PW_RENDERFULLCONTENT = 2,这应该有助于使用正确的框架而不是经典框架来渲染窗口(另请参见https://stackoverflow.com/a/40042587/4313487

我有2台具有相同规格的PC。在第一台PC上,图像以镜像方式打印,在第二台PC上,图像以原始显示的方式打印。

两台PC的Windows 10都具有相同的区域和区域设置。在两台PC上,消息框窗口具有相同的样式标志,包括WS_EX_LAYOUTRTL。

来自PC1的图像-被镜像:

enter image description here

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

enter image description here

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

enter image description here

为什么会发生?

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

解决方法

如果不建议使用。什么是最好的打印方式 窗口应用程序(例如铬),如果没有此标志,则该应用程序是 呈现为黑屏?

我使用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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?