当前位置: 首页 > news >正文

做外贸在什么网站好安徽网络推广新手

做外贸在什么网站好,安徽网络推广新手,深圳网站建设服务公,进网站显示建设中怎么解决Qt 基于FFmpeg的视频转换器 - 转GIF动图 引言一、设计思路二、核心源码三、参考链接 引言 gif格式的动图可以通过连续播放一系列图像或视频片段来展示动态效果#xff0c;使信息更加生动形象#xff0c;可以很方便的嵌入到网页或者ppt中。上图展示了视频的前几帧转为gif动图的… Qt 基于FFmpeg的视频转换器 - 转GIF动图 引言一、设计思路二、核心源码三、参考链接 引言 gif格式的动图可以通过连续播放一系列图像或视频片段来展示动态效果使信息更加生动形象可以很方便的嵌入到网页或者ppt中。上图展示了视频的前几帧转为gif动图的效果 (转了7%直接取消了)。 之前写过一个基于python的 MP4视频转GIF动图速度略慢且不容易打包 (体积很大)故基于c写一个小程序方便日常使用. (这里推荐几个gif生成的小工具 - GifCam、ScreenGif.exe、LICEcap.exe等等 or 直接使用ffmpeg提供的小工具) 本文思路基于FFmpeg进行视频的读取解码成一张张图片调用gif.h将图片写入gif gif-h官方git地址https://github.com/charlietangora/gif-h 一、设计思路 可参考之前的博客Qt 基于FFmpeg的视频播放器 - QtFFmpegPlayer 和之前的视频播放器play()函数类似实现savetoGif()函数将视频的一帧解码成图片后立即写入gif文件 GifWriteFrame(writer, image.bits(),static_castuint32_t(avcodec_context-width),static_castuint32_t(avcodec_context-height),static_castuint32_t(100/this-m_fps), // 单位是1/100秒即10ms8, true);frame_id;qDebug()QString(当前转换第 %1 帧).arg(frame_id);emit sig_SendFrameNum(frame_id);创建新的FFmpegVideo类和新的处理线程避免与播放线程冲突 m_FFmpegProcessing new FFmpegVideo(); m_ProcessingThread new QThread(this); m_FFmpegProcessing-moveToThread(m_ProcessingThread); // 移动到线程中创建非模态的进度条发送sig_SendFrameNum帧数信号设置进度条进度 同时判断是否点击了进度条的按钮 (稳妥起见此连接设置为Qt::BlockingQueuedConnection - 确定同步执行对m_stopProcessing 及时赋值) // 进度条progressDialog new QProgressDialog();progressDialog-setMinimumWidth(300); // 设置最小宽度progressDialog-setWindowModality(Qt::NonModal); // 非模态其它窗口正常交互 Qt::WindowModal 模态progressDialog-setMinimumDuration(0); // 等待0秒后显示progressDialog-setWindowTitle(tr(进度条框)); // 标题名progressDialog-setLabelText(tr(正在转换)); // 标签的progressDialog-setCancelButtonText(tr(放弃)); // 取消按钮progressDialog-setRange(0, static_castint(m_FFmpegProcessing-m_frame_num)); // 考虑是否移换种方式显示进度条进度... 不使用帧数// 进度条绑定 connect(m_FFmpegProcessing, FFmpegVideo::sig_SendFrameNum, this, [](int num){if(progressDialog-wasCanceled()){ // 弹窗的取消按钮m_FFmpegProcessing-m_stopProcessing true;return;}progressDialog-setValue(num);}, Qt::BlockingQueuedConnection); // 发送信号后先执行此内容 再继续执行线程保证线程可以及时推出使用lambda表达式接收信号需要注意其默认参数… 建议写完整防止奇奇怪怪的问题 Qt使用connect连接信号与lambda表达式需要注意https://blog.csdn.net/qq_17769915/article/details/132609165 qt 如何使用 lamda 表达式接收线程中发射的数据并在里面更新 UI https://www.cnblogs.com/cheungxiongwei/p/10895172.html 子线程中会判断m_stopProcessing - 是否点击了进度条的退出按钮. 如果点击了按钮最后也会执行GifEnd生成一个不完整的gif while(this-m_stopProcessing false)GifEnd(writer); // 取消之后是否需要保存不完整的gif? 暂时保存使用事件循环信号stop变量sleep阻塞QWaitConditionQMutex条件变量退出子线程工作https://blog.csdn.net/u012999461/article/details/127204493 进度条在函数中new的子线程结束之后需释放deleteLater。 还有一些小问题… 比如点两次另存为gif可以同时弹出两个进度条等等 - 进度条没必要每次都new… 后续继续改进 // 开始转换 在这里连接需注意Qt::UniqueConnection 使得连接唯一 connect(m_ProcessingThread, SIGNAL(started()), m_FFmpegProcessing, SLOT(savetoGif()), Qt::UniqueConnection); connect(m_ProcessingThread, QThread::finished, progressDialog, QProgressDialog::deleteLater, Qt::UniqueConnection); m_ProcessingThread-start(); m_ProcessingThread-quit();二、核心源码 其他源码可参考我之前的博客Qt 基于FFmpeg的视频播放器 - QtFFmpegPlayer FFmpegVideo::savetoGif() void FFmpegVideo::savetoGif() {qDebug()savetoGif;//avformat_seek_file()GifWriter writer {};GifBegin(writer, this-m_outfilename.toStdString().c_str(),static_castuint32_t(avcodec_context-width),static_castuint32_t(avcodec_context-height),static_castuint32_t(100/this-m_fps), // 单位是1/100秒即10ms8, true );// 初始化临时变量AVPacket* av_packet static_castAVPacket*(av_malloc(sizeof(AVPacket)));AVFrame *pFramein av_frame_alloc(); //输入和输出的帧数据AVFrame *pFrameRGB av_frame_alloc();uint8_t * pOutbuffer static_castuint8_t *(av_malloc( //缓冲区分配内存static_castquint64(av_image_get_buffer_size(AV_PIX_FMT_RGBA,avcodec_context-width,avcodec_context-height,1))));// 初始化缓冲区av_image_fill_arrays(pFrameRGB-data,pFrameRGB-linesize,pOutbuffer,AV_PIX_FMT_RGB32,avcodec_context-width, avcodec_context-height, 1);// 格式转换SwsContext* pSwsContext sws_getContext(avcodec_context-width, // 输入宽avcodec_context-height, // 输入高avcodec_context-pix_fmt, // 输入格式avcodec_context-width, // 输出宽avcodec_context-height, // 输出高AV_PIX_FMT_RGBA, // 输出格式SWS_BICUBIC, ///todonullptr,nullptr,nullptr);int ret0;int frame_id 0;this-m_stopProcessing false;// 开始循环while(this-m_stopProcessing false){if (av_read_frame(avformat_context, av_packet) 0){if (av_packet-stream_index av_stream_index){avcodec_send_packet(avcodec_context, av_packet); // 解码ret avcodec_receive_frame(avcodec_context, pFramein); // 获取解码输出if (ret 0){sws_scale(pSwsContext, //图片格式的转换static_castconst uint8_t* const*(pFramein-data),pFramein-linesize, 0, avcodec_context-height,pFrameRGB-data, pFrameRGB-linesize);QImage *tmpImg new QImage(static_castuchar *(pOutbuffer),avcodec_context-width,avcodec_context-height,QImage::Format_RGBA8888);QImage image tmpImg-copy();GifWriteFrame(writer, image.bits(),static_castuint32_t(avcodec_context-width),static_castuint32_t(avcodec_context-height),static_castuint32_t(100/this-m_fps), // 单位是1/100秒即10ms8, true);frame_id;qDebug()QString(当前转换第 %1 帧).arg(frame_id);emit sig_SendFrameNum(frame_id);//break;}}}}GifEnd(writer); // 取消之后是否需要保存不完整的gif? 暂时保存av_packet_unref(av_packet); }MainWindow::saveVideo() void MainWindow::saveVideo() {if(!m_FFmpegVideo){return;}m_FFmpegProcessing-loadVideoFile(m_FFmpegVideo-m_filename); // 读取视频QFileInfo fileInfo(m_FFmpegProcessing-m_filename);QString filePath QFileDialog::getSaveFileName(this, QObject::tr(Open File),fileInfo.completeBaseName() .gif,QObject::tr(gif (*.gif) ;; All Files (*)));m_FFmpegProcessing-m_outfilename filePath; // 输出文件fileInfo.setFile(filePath);// 转GIF ------------int ret fileInfo.suffix().compare(QString(gif), Qt::CaseInsensitive);// 进度条progressDialog new QProgressDialog();progressDialog-setMinimumWidth(300); // 设置最小宽度progressDialog-setWindowModality(Qt::NonModal); // 非模态其它窗口正常交互 Qt::WindowModal 模态progressDialog-setMinimumDuration(0); // 等待0秒后显示progressDialog-setWindowTitle(tr(进度条框)); // 标题名progressDialog-setLabelText(tr(正在转换)); // 标签的progressDialog-setCancelButtonText(tr(放弃)); // 取消按钮progressDialog-setRange(0, static_castint(m_FFmpegProcessing-m_frame_num)); // 考虑是否移换种方式显示进度条进度... 不使用帧数// 转换if(ret 0){// 进度条绑定connect(m_FFmpegProcessing, FFmpegVideo::sig_SendFrameNum, this, [](int num){if(progressDialog-wasCanceled()){ // 弹窗的取消按钮m_FFmpegProcessing-m_stopProcessing true;return;}progressDialog-setValue(num);}, Qt::BlockingQueuedConnection); // 发送信号后先执行此内容 再继续执行线程保证线程可以及时推出// 开始转换 在这里连接需注意Qt::UniqueConnection 使得连接唯一connect(m_ProcessingThread, SIGNAL(started()), m_FFmpegProcessing, SLOT(savetoGif()), Qt::UniqueConnection);connect(m_ProcessingThread, QThread::finished, progressDialog, QProgressDialog::deleteLater, Qt::UniqueConnection);m_ProcessingThread-start();m_ProcessingThread-quit();} }三、参考链接 直接调用工具 用ffmpeg提供的工具将视频转成gif动图https://blog.csdn.net/xindoo/article/details/127603896 Android录屏并利用FFmpeg转换成gifhttps://blog.csdn.net/MingHuang2017/article/details/79186527 代码实现 Qt项目中实现屏幕截图并生成gif的详细示例https://www.zhihu.com/tardis/bd/art/194303756 Qt编写自定义控件35-GIF录屏控件https://developer.aliyun.com/article/712842 ffmpeg生成gif动图https://www.jianshu.com/p/d9652fc2e3fd FFmpeg进阶: 截取视频生成gif动图https://zhuanlan.zhihu.com/p/628705382
http://www.dnsts.com.cn/news/118269.html

相关文章:

  • 无锡做家纺公司网站苏州新区网页设计培训
  • 机械类 网站源码基金从业培训网站
  • 一个服务器上有两个网站 要备案两次吗怎样做像绿色和平组织类似的网站
  • 现在流行什么语言建设网站芜湖seo网站优化
  • 建立企业网站步骤wordpress 旅游 主题
  • 沧州网站建设设计太原网络推广
  • 手机如何做软件淘宝客网站做seo
  • 南宁兴宁区建设局网站h5制作报价细则
  • 网站跳出打开上次浏览的网站模板
  • 网站建设跟前端有什么区别全国门户网站有哪些
  • 公司自建网站万户网络做网站怎么样
  • 丽水房产网站建设企业logo标志设计公司
  • 优化网站工具怎么建设电子邮箱网站
  • 湘西州建设银行网站北京网站建设 乐云seo
  • 扬州电子商务网站建设百度云分享tp响应式网站开发
  • 广州番禺专业做网站网络营销案例并分析
  • h5 服装网站模板windows优化大师有用吗
  • 个人可以备案什么网站超级外链工具 增加外链中
  • 上海自主建站模板个人博客网页
  • wordpress汽配网站深圳建网站服务商
  • 城乡建设网站证件查询热点新闻事件
  • 做京东网站的摘要高平做网站
  • 四川兴昌建设有限公司网站景区网站建设策划书
  • 企业网站模板下载需谨慎备案的域名拿来做别的网站
  • 网站建设佛网站开发与管理专业的就业信息
  • 做网站head.htmseo查询seo
  • 张家港网站建设培训班帮助设计的网站
  • 商业网站的建设流程铁岭新区旅行社电话
  • 收录查询 站长工具wordpress 调用评论框
  • 网站优化建议个人网页设计思路怎么写