一:截取整个屏幕

(1)代码如下:

void

Test::slotGrabFullScreen()

{

QScreen *screen = QGuiApplication::primaryScreen();

QString

filePathName = "full-";

filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");

filePathName += ".jpg";

if(!screen->grabWindow(0).save(filePathName, "jpg"))

{

cout<

}

}

(2)效果如下图:

注意:此方法用于保存整个屏幕。

二:截取某个控件(QWidget)

(1)代码如下:

void

Test::slotGrabWidgetScreen()

{

QRect

rect = ui.vw->geometry();

QPixmap

p = this->grab(QRect(0, 0, 1000, 800));

QString

filePathName = "widget";

filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");

filePathName += ".png";

if(!p.save(filePathName,"png"))

{

cout<

}

}

调用QWidget的grab方法。

(2)效果图:

注意:此方法对截取播放视频的widget无效。播放视频的widget(QVideoWidget)

三:截取视频图片

方法:先截取整个屏幕,保存为图片,然后计算获取到视频在图片的位置。

(1)代码如下:

void

Test::slotCutScreen()

{

// 保存整个屏幕为QPixmap

QScreen *screen = QGuiApplication::primaryScreen();

QString

filePathName = "cut-";

filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");

filePathName += ".png";

QPixmap

pixmap = screen->grabWindow(0);

if(!pixmap.save(filePathName,"png"))

{

cout<

}

// 计算视频的位置和大小

cout<

QRect

geo = this->geometry();

QRect

appGeo = geo; // 整个应用程序在图片中的位置。

cout<

geo = ui.vw->geometry(); // 播放视频在图片中的位置。

cout<

QWidget *centerWidget = centralWidget(); // QMainWindow在应用程序的位置

QRect

centerRect = centerWidget->geometry();

cout<

QRect

copyGeo;

copyGeo.setX(geo.x() + appGeo.x() + centerRect.x()); // x=三个x相加

copyGeo.setY(geo.y() + appGeo.y() + centerRect.y());

copyGeo.setWidth(geo.width());

copyGeo.setHeight(geo.height());

cout<

QPixmap

pixmapCopy = pixmap.copy(copyGeo); // copy图片

filePathName.prepend("Copy+");

if(!pixmapCopy.save(filePathName,"png"))

{

cout<

}

}

(2)效果图:整个屏幕

(3)截取视频

注意:此方法有两个弊端

A:此方法截图的视频图片与窗口大小有关。有可能截取出来的像素非常低(播放视频的窗口很小)

B:如果视频的分辨率与窗口大小不一致,则截取出来的图片有黑边框。(看上图左右两边有黑色边框)

三、利用FFMPEG获取视频图片

处理步骤:

1:获取一帧数据

2:利用FFMPEG将YUV格式转换为RGB格式

3:保存图片

(1)源代码

// 以下是两个成员变量。一个是player,一个是侦测帧对象

QMediaPlayer *mPlayer;

QVideoProbe *mVideoProbe;

void

Test::slotGrabMediaScreenFFMPEG()

{

connect(mVideoProbe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(slotProcessFrameFFMPEG(QVideoFrame)));

}

void

Test::slotProcessFrameFFMPEG(const

QVideoFrame & buffer)

{

disconnect(mVideoProbe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(slotProcessFrameFFMPEG(QVideoFrame)));

if(!buffer.isValid()) // 数据是否有效

{

cout<

connect(mVideoProbe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(slotProcessFrame(QVideoFrame)));

return;

}

QImage

img;

QVideoFrame

frame(buffer); // 拷贝数据

frame.map(QAbstractVideoBuffer::ReadOnly); // 将视频缓存映射到内存中

int

totalBytes = frame.width() * frame.height() * 3;

uchar *imageBuffer = (uchar*)malloc(totalBytes);

if(!YV12ToARGB24_FFmpeg(frame.bits(), imageBuffer, frame.width(), frame.height()))

{

cout<

return;

}

img = QImage(imageBuffer, frame.width(), frame.height(), //frame.bytesPerLine(),

//imageFormat);

QImage::Format_RGB888);

QString

filePathName = "convert-vedio-";

filePathName += QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz");

filePathName += ".png";

if(!img.save(filePathName,"png"))

{

cout<

}

}

bool

Test::YV12ToARGB24_FFmpeg(unsigned

char* pYUV,unsigned

char* pBGR24,int

width,int

height)

{

if (width < 1 || height < 1 || pYUV == NULL || pBGR24 == NULL)

return

false;

AVPicture

pFrameYUV, pFrameBGR;

avpicture_fill(&pFrameYUV, pYUV, PIX_FMT_NV12, width, height);

avpicture_fill(&pFrameBGR, pBGR24, AV_PIX_FMT_RGB24, width,height);

struct

SwsContext* imgCtx = NULL;

imgCtx = sws_getContext(width, height, PIX_FMT_NV12, width, height, AV_PIX_FMT_RGB24, SWS_BICUBIC, 0, 0, 0);

if (imgCtx != NULL){

sws_scale(imgCtx, pFrameYUV.data, pFrameYUV.linesize, 0, height, pFrameBGR.data, pFrameBGR.linesize);

if(imgCtx){

sws_freeContext(imgCtx);

imgCtx = NULL;

}

return

true;

}

else{

sws_freeContext(imgCtx);

imgCtx = NULL;

return

false;

}

}

(2)效果图

注意:这样就把视频给截取出来了。完全和视频一致。

关于FFMPEG的搭建,见

http://blog.csdn.net/huangqi734044860/article/details/60956995

五:结论

终于搞定了。

qt截图怎样实现橡皮擦_利用QT实现截屏的四种方法相关推荐

  1. 在struts2中push方法的使用_电脑使用中怎么截屏的几种方法

    电脑在日常工作中经常需要用到截屏的操作,为了截取画面提供证明或者说明,像我就经常需要用到,当然我在写文章的时候更是需要用到,来配合文字的描述,使大家能更直观更容易的去操作,以达到快速解决电脑问题的目的 ...

  2. android平板怎么截图,在安卓手机或平板电脑上截屏的5种方法,学起来!

    在Android手机或平板电脑上截屏并不是随便按下一个按钮那样简单,尤其是当你尝试捕获运动中的特定场景(例如游戏或视频),或者你担心可能会消失的屏幕时,以及当你正打算截屏,但是一不小心把手机屏幕关了的 ...

  3. html特殊字符p如何屏蔽 asp,利用asp去除html标记的四种方法

    利用asp去除html标记的四种方法 发布日期:2015-10-8 16:10:45 利用asp去除html标记的四种方法 方法一 : 使用"" 如果您想要知道如何从文本中删除ht ...

  4. android华为怎么截屏快捷键,华为p10怎么截图 华为p10截屏的三种方法

    华为p10怎么截屏和保存图片以及华为p10截屏快捷键在哪是很多朋友问到的,对于刚入手华为p10的朋友来说可能有些基本操作是不知道的,这里我们一起来了解一下华为p10怎么截屏和保存图片以及华为p10截屏 ...

  5. 怎么用计算机直接截图,电脑怎么快速截屏?分享电脑快速截屏的五种方法

    工作的时候经常遇到需要屏幕截图,只要提到截屏,大家立马就想到了QQ截屏,虽然此方法也不错,但每次都要登录QQ,略微有点麻烦,有些什么其他的快捷方法吗?答案是有的,这里教大家电脑截图快捷键操作方法. 具 ...

  6. python单向认证_使用Python进行单向方差分析的四种方法

    python单向认证 The current post will focus on how to carry out between-subjects ANOVA using Python. As m ...

  7. python如何用macd选股_使用MACD指标进行选股的四种方法

    股价一个底比一个底低,而相对的MACD两个金叉点底部抬高,即底背离,说明市场已经进入跌无可跌的状态,开始出现反弹或者反转的需求.MACD金叉向上,DIF出现红柱,代表市场即将发动攻击,快速线起到助涨作 ...

  8. redhat7图形界面网卡设置_初学Linux之配置网卡的四种方法

    方法1:是否正确配置网卡IP地址是两台服务器是否可以相互通信的前提,而在Linux系统中一切都是文件,因此配置网络服务即是编辑网卡的配置文件. 现在以RHEL7系统为例配置网卡,先进入RHEL7系统中 ...

  9. 【Qt】QTableView中嵌入复选框CheckBox 的四种方法总结

    搜索了一下,QTableView中嵌入复选框CheckBox方法有四种: 第一种不能之前显示,必须双击/选中后才能显示,不适用. 第二种比较简单,通常用这种方法. 第三种只适合静态显示静态数据用 第四 ...

最新文章

  1. iOS-查询数据库--指定数据表中的当前数据行的总数量
  2. redhat6.5 yum源
  3. 100c之37:爱因斯坦问题
  4. 使用MyEclipse开发第一个Web程序
  5. 这种有序神经元,像你熟知的循环神经网络吗?
  6. 《云计算》学习笔记1
  7. 领域应用 | 知识图谱在小米的应用与探索
  8. 程序员美团面试挂了,7天后去腾讯面试,见到面试官:好巧啊!!
  9. java extjs4 分页_extjs学习笔记(四)带分页的grid
  10. 如何用分库分表的9种分布式主键ID生成方案?附小技巧
  11. java中if条件中删除此行代码_Java中我如何去除if...else...语句?
  12. 设置和使用地图的范围—ArcGIS API for JavaScript
  13. CentOS添加新角色(新增一个具有root权限的新用户)
  14. 《机器学习实战》原书数据与代码(基于Python3)汇总
  15. 在SQL Server 语句中,如何将参数做为表名传递到查询语句中
  16. js代码:轮播图的简单实现
  17. 控制系统中对信号求导的注意事项
  18. 2023年入学华东师范大学MBA提前面试流程及时间-文都管联院
  19. python的tkinter插入图片_如何用python tkinter插入显示图片?
  20. C++实现推箱子游戏

热门文章

  1. 来自运维伪大佬的叨叨
  2. 【李宏毅2020 ML/DL】P20-21 Recurrent Neural Network | “Deep and structure is future.“
  3. 【数据结构笔记14】微软面试经典 - 逆转链表问题(Reversing Linked List)
  4. java基本类型引用类型_Java基本类型和引用类型
  5. React Native 0.20官方入门教程
  6. python pathos_python运行多线程库pathos时,pymongo递归深度溢出
  7. windows下bat批处理实现守护进程
  8. 前端 JavaScript 之『防抖』的简单代码实现
  9. 不要再危言耸听!家用电脑辐射全揭秘
  10. diy 单片机 自动浇花_造个自动浇花装置(完)