Xlib 应用被覆盖遮挡或者移出屏幕时,获取窗口截图
在https://www.cnblogs.com/chaichengxun/p/15409996.html这篇文章里已经讲过,如果应用窗口位于屏幕外或者被遮挡,xlib不能获取完整的应用窗口截屏,如下
今天就来解决这个问题。
用到的头文件:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xrender.h>
用到的库:
-lXlib -lXcomposite -lXrender
代码:
static Display *xdisplay = 0; Display *disp() { if (!xdisplay) xdisplay = XOpenDisplay(NULL); return xdisplay; } XImage* GetDrawableThumbnail(Drawable src_drawable, Visual* visual, int src_width, int src_height) { XRenderPictFormat* format = XRenderFindVisualFormat(disp(), visual); if (!format) { cout <<"XRenderFindVisualFormat() failed"; return NULL; } XRenderPictureAttributes pa; pa.subwindow_mode = IncludeInferiors; Picture src = XRenderCreatePicture(disp(), src_drawable, format, CPSubwindowMode, &pa); if (!src) { cout << "XRenderCreatePicture() failed"; return NULL; } Pixmap dst_pixmap = XCreatePixmap(disp(), src_drawable, src_width, src_height, format->depth); if (!dst_pixmap) { cout << "XCreatePixmap() failed"; XRenderFreePicture(disp(), src); return NULL; } Picture dst = XRenderCreatePicture(disp(), dst_pixmap, format, 0, NULL); if (!dst) { cout << "XRenderCreatePicture() failed"; XFreePixmap(disp(), dst_pixmap); XRenderFreePicture(disp(), src); return NULL; } XRenderColor transparent = {0}; XRenderFillRectangle(disp(), PictOpSrc, dst, &transparent, 0, 0, src_width, src_height); XTransform xform = { { { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) } } }; XRenderSetPictureTransform(disp(), src, &xform); XRenderSetPictureFilter(disp(), src, FilterBest, NULL, 0); XRenderComposite(disp(), PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, src_width, src_height); XImage* image = XGetImage(disp(), dst_pixmap, 0, 0, src_width, src_height, AllPlanes, ZPixmap); return image; }
将XImage转换成QPixmap:
void AppListSelDlg::GetPixmap(unsigned long win, QPixmap &pixmap) { Display *display_ = disp(); XCompositeRedirectWindow(display_, win, CompositeRedirectAutomatic); Pixmap src_pixmap = XCompositeNameWindowPixmap(display_, win); if (!src_pixmap) { printf("XCompositeNameWindowPixmap() failed"); return; } XWindowAttributes attr; if (!XGetWindowAttributes(display_, win, &attr)) { printf( "XGetWindowAttributes() failed"); XFreePixmap(display_, src_pixmap); return ; } XImage* pImage = XCompcap::GetDrawableThumbnail(src_pixmap, attr.visual, attr.width, attr.height); QImage image = QImage((const uchar *)(pImage->data), pImage->width, pImage->height, pImage->bytes_per_line, QImage::Format_RGB32); pixmap = QPixmap::fromImage(image); XDestroyImage(pImage); XFreePixmap(display_, src_pixmap); }
看一下实际效果:
可以看出,虽然终端遮挡住了文件夹,但是获取到的图像仍然是完整的图像。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南