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

重庆网站建设mswzjsaso优化公司

重庆网站建设mswzjs,aso优化公司,凤泉网站建设,广东省住房和建设委员会网站实现思路 🤔​ 基于ffmpeg,画布的方式,创建画布 -> 水印 -> 旋转 -> 抠图 -> 叠加到图像上基于ffmpeg,旋转图片的方式,填充 -> 水印 -> 顺时针旋转 -> 逆时针旋转 -> 截图基于opencv&#xff…

在这里插入图片描述

实现思路 🤔​

  1. 基于ffmpeg,画布的方式,创建画布 -> 水印 -> 旋转 -> 抠图 -> 叠加到图像上
  2. 基于ffmpeg,旋转图片的方式,填充 -> 水印 -> 顺时针旋转 -> 逆时针旋转 -> 截图
  3. 基于opencv,创建画布 -> 水印 -> 仿射变换 -> 水平垂直拼接 -> 叠加图片上

经测试比对,opencv实现方式效率是最快的


代码实现 💨

  1. FFmpeg
    1. 旋转画布方式

      • 这种方式相对实现简单一些,但经过试验,对于一个2k的视频,实现全屏文字倾斜,效率太慢了 。不知道是我代码问题,还是什么问题。如果有大佬能提高效率,方便指导一二,抱拳了.
      • 实现参考
        • https://blog.csdn.net/qq_38722827/article/details/121549999
        • https://blog.csdn.net/qq_23282479/article/details/119904850
    2. 旋转图片方式

      1. 思路:
        • 首先将图片填充放大,然后计算出水印位置,叠加水印,再逆时针将图片旋转回来,字体就变斜了。然后通过剪裁,将图片剪切成原图大小。
      2. 基于 ffmpeg filter 实现
      	// 填充// [in]scale=原图宽:原图高,pad=填充后宽:填充后高:填充左右大小:填充上下大小:black[out]// 四周填充,  pad 输入尺寸的一半char dtext[512];snprintf(dtext, sizeof(dtext), "[in]scale=%d:%d,pad=%d:%d:%d:%d:black[out]",frameWidth, frameHeight, expandFrameWidth, expandFrameHeight, expandSize, expandSize);// 水印// inxxxx[a];[a]xxx[a];[a]xxx[out]  中间传的文字标签首位对应([a] [a]). 结束没有';'. char dtext[1000];snprintf(dtext, sizeof(dtext), "[in]drawtext=fontfile=%s:text=%s:x=%d:y=%d:fontsize=%d:fontcolor=%s:alpha=%.1f[a];",kFont, txt.c_str(), start_x, start_y, kFontSize, kFontColor, italicTextInfo_.alpha);// 翻转// [in]rotate=PI* angel /180[out] char dtext[512];snprintf(dtext, sizeof(dtext), "[in]rotate=PI* %d /180[out]", angel);// 截取 // [in]crop=原图宽:原图高:截取x:截取y[out]char dtext[512];snprintf(dtext, sizeof(dtext), "[in]crop=%d:%d:%d:%d[out]", frameWidth, frameHeight, startx, starty);
      
      1. 创建 AVFilterGraph
      int init_filter_graph(const std::string& filter) {filterGraph_ = avfilter_graph_alloc();const AVFilter* buffersrc = avfilter_get_by_name("buffer");const AVFilter* buffersink = avfilter_get_by_name("buffersink");char args[512];snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", frameWidth_, frameHeight_, frameFormat_, 1, videoFps_, 1, 1);int ret = avfilter_graph_create_filter(&buffersrcCtx_, buffersrc, "in", args, NULL, filterGraph_);if (ret < 0){avfilter_graph_free(&filterGraph_);filterGraph_ = NULL;return -1;}// buffer video sink: to terminate the filter chain.enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, AV_PIX_FMT_NONE };AVBufferSinkParams* buffersink_params = av_buffersink_params_alloc();buffersink_params->pixel_fmts = pix_fmts;ret = avfilter_graph_create_filter(&buffersinkCtx_, buffersink, "out", NULL, buffersink_params, filterGraph_);av_free(buffersink_params);if (ret < 0){avfilter_graph_free(&filterGraph_);filterGraph_ = NULL;return -1;}AVFilterInOut* outputs = avfilter_inout_alloc();/* Endpoints for the filter graph. */outputs->name = av_strdup("in");outputs->filter_ctx = buffersrcCtx_;outputs->pad_idx = 0;outputs->next = NULL;AVFilterInOut* inputs = avfilter_inout_alloc();inputs->name = av_strdup("out");inputs->filter_ctx = buffersinkCtx_;inputs->pad_idx = 0;inputs->next = NULL;if ((ret = avfilter_graph_parse_ptr(filterGraph_, filter.c_str(), &inputs, &outputs, NULL)) < 0)goto end;ret = avfilter_graph_config(filterGraph_, NULL);if (ret < 0)goto end;
      end:avfilter_inout_free(&inputs);avfilter_inout_free(&outputs);return ret;
      }
      
      1. 向滤波输入帧, 然后从FilterGraph中取出一个AVFrame
      	AVFrame* overlay(AVFrame* in) {if (!isInit_)return nullptr;int ret = av_buffersrc_add_frame(buffersrcCtx_, in);if (ret < 0)return nullptr;ret = av_buffersink_get_frame(buffersinkCtx_, out_);if (ret < 0){av_frame_unref(out_);return nullptr;}return out_;}
      
      1. 生成对应 filter , 然后 向滤波中输入帧
      // 大概流程思路
      void xxxxx(){...// 生成对应filterstd::string filter = "对应filter";init_filter_graph(filter);...while (true){ret = av_read_frame(ifmtCtx, pkt);if (ret < 0)goto end;// audioif (pkt->stream_index == aistream) {av_packet_unref(pkt);continue;}// decode encode pktret = avcodec_send_packet(deCodecCtx, pkt);if (ret < 0)goto end;while (ret >= 0) {ret = avcodec_receive_frame(deCodecCtx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {break;}else if (ret < 0) {goto end;}// solove [libx264 @ 0x34b88a0] specified frame type (3) at 0 is not compatible with keyframe intervalframe->pict_type = AV_PICTURE_TYPE_NONE;// overlay italic txt infoAVFrame* overlay_frame = overlay(frame);if (overlay_frame == nullptr)goto end;ret = encode_frame_to_write_file(enCodecCtx, overlay_frame, pkt, ifmtCtx->streams[vistream]->time_base, ofmtCtx->streams[vostream]->time_base, ofmtCtx);if (ret < 0) {av_frame_free(&overlay_frame);goto end;}av_packet_unref(pkt);av_frame_unref(frame);av_frame_unref(overlay_frame);}#pragma endregionav_packet_unref(pkt);}...}
      

在这里插入图片描述

  1. Opencv
    1. 思路
      • 先创建一张斜体水印的画布,然后重复叠加到每一张图片上,这样可以提高很大的效率。
    2. 代码
      1. 创建斜体水印
        int init_water_mark(const std::string& txt, cv::Mat& water) {// 原图宽高int imageW = italicTextInfo_.frameWidth / italicTextInfo_.col;int imageH = italicTextInfo_.frameHeight / italicTextInfo_.row;cv::Mat canvasMat = cv::Mat::zeros(cv::Size(imageW, imageH), CV_8UC3);// 水印,使用 Times New Roman 字体VTText::putTextHuskyC(canvasMat, txt.c_str(), cv::Scalar(255, 255, 255), kFontSize, "Times New Roman", false, false);// 实际显示的水印行列数int w_count = italicTextInfo_.col * 2 - 1;int h_count = italicTextInfo_.row * 2;// 垂直拼接水印std::vector<cv::Mat> vImgs;cv::Mat vResult;for (int vi = 0; vi < h_count; vi++)vImgs.push_back(canvasMat);vconcat(vImgs, vResult);// 水平拼接水印std::vector<cv::Mat> hImgs;cv::Mat hResult;for (int hi = 0; hi < w_count; hi++)hImgs.push_back(vResult);hconcat(hImgs, hResult);cv::Point2f center(hResult.cols / 2.0, hResult.rows / 2.0);// 通过仿射变换将水印旋转45度,实现全屏斜体效果cv::Mat rotation_matix = getRotationMatrix2D(center, italicTextInfo_.italicAngel, 1.0);cv::Mat rotated_image;warpAffine(hResult, rotated_image, rotation_matix, hResult.size());// 然后将水印图裁剪成原图大小,用于后续叠加到原图上.water = rotated_image(cv::Rect((hResult.cols - italicTextInfo_.frameWidth) / 2, (hResult.rows - italicTextInfo_.frameHeight) / 2, italicTextInfo_.frameWidth, italicTextInfo_.frameHeight));return 0;}// 将水印图叠加到原图上// frame: 解码帧 avframe AVFrame* overlayItalicTextInfoCVCanvas(AVFrame* frame) {//cv::Mat src_mat;//frame_to_mat(frame, src_mat);int pktSize;uint8_t* buffer_rgb = convertRgb(frame, frame->width, frame->height, AV_PIX_FMT_YUV420P, frame->width, frame->height, AV_PIX_FMT_BGR24, pktSize);cv::Mat src_mat = cv::Mat(frame->height, frame->width, CV_8UC3, buffer_rgb);cv::Mat roi;roi = src_mat(cv::Rect(0, 0, watermark_.cols, watermark_.rows));cv::addWeighted(roi, 1.0, watermark_, italicTextInfo_.alpha, 0, roi);AVFrame* dst = mat_to_frame(src_mat, src_mat.cols, src_mat.rows, AV_PIX_FMT_YUV420P);if (buffer_rgb != nullptr)av_free(buffer_rgb);return  dst;}
        
        1. 大概流程
        void xxxxx(){...// 先创建个带有斜体水印的matcv::Mat water;const std::string txt = "12321321";init_water_mark(txt, water)...while (true){ret = av_read_frame(ifmtCtx, pkt);if (ret < 0)goto end;// audioif (pkt->stream_index == aistream) {av_packet_unref(pkt);continue;}// decode encode pktret = avcodec_send_packet(deCodecCtx, pkt);if (ret < 0)goto end;while (ret >= 0) {ret = avcodec_receive_frame(deCodecCtx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {break;}else if (ret < 0) {goto end;}// solove [libx264 @ 0x34b88a0] specified frame type (3) at 0 is not compatible with keyframe intervalframe->pict_type = AV_PICTURE_TYPE_NONE;// overlay italic txt infoAVFrame* overlay_frame = overlayItalicTextInfo(frame);if (overlay_frame == nullptr)goto end;ret = encode_frame_to_write_file(enCodecCtx, overlay_frame, pkt, ifmtCtx->streams[vistream]->time_base, ofmtCtx->streams[vostream]->time_base, ofmtCtx);if (ret < 0) {av_frame_free(&overlay_frame);goto end;}av_packet_unref(pkt);av_frame_unref(frame);av_frame_unref(overlay_frame);}#pragma endregionav_packet_unref(pkt);}...}
        

在这里插入图片描述


整理个demo,基于opencv实现的。demo中 需依赖 opencv ffmpeg ,自己搭建个环境即可运行。

demo: https://download.csdn.net/download/haiyangyunbao813/87499341


参考文章 ✨​

  • https://blog.csdn.net/qq_23282479/article/details/119904850
  • https://blog.csdn.net/qq_38722827/article/details/121549999

总结 👊​

  1. 经测试,基于opencv方式,相比较ffmpeg filter ,效率至少能提升2倍。(1920 * 1080 i7 6代u)
    • opencv : 平均一帧 20ms
    • ffmpeg : 平均一帧 50ms
  2. 基于ffmpeg filter, 我感觉应该是可以提升效率的,我的想法先创建出来水印,然后重复叠加到每一张frame上就行,但效率总是提升不了,希望哪位大佬有时间能帮忙试试,或者有什么别的好的方式,抱拳了。
  3. 以上就是我分享的全部内容了,有不对的地方好,欢迎留言指正。有需要的小伙伴,可以参考参考。

最后来个三连,今年就属你最牛逼了 🚀​

在这里插入图片描述


文章转载自:
http://dinncopiecewise.tqpr.cn
http://dinncomollification.tqpr.cn
http://dinncobibliopegistic.tqpr.cn
http://dinncolathe.tqpr.cn
http://dinncophotogene.tqpr.cn
http://dinncolouie.tqpr.cn
http://dinncoragpicker.tqpr.cn
http://dinncophlebology.tqpr.cn
http://dinncoblasted.tqpr.cn
http://dinncosensitometer.tqpr.cn
http://dinncocragginess.tqpr.cn
http://dinncotransfluence.tqpr.cn
http://dinncodelime.tqpr.cn
http://dinncocoelomatic.tqpr.cn
http://dinncopaltrily.tqpr.cn
http://dinncosourcebook.tqpr.cn
http://dinncoerysipeloid.tqpr.cn
http://dinncorealisable.tqpr.cn
http://dinncosalverform.tqpr.cn
http://dinncopalladize.tqpr.cn
http://dinncoshipside.tqpr.cn
http://dinncoovariole.tqpr.cn
http://dinncocoastal.tqpr.cn
http://dinncocomdex.tqpr.cn
http://dinncounfortunate.tqpr.cn
http://dinncoenunciator.tqpr.cn
http://dinncobarbuda.tqpr.cn
http://dinncotalcky.tqpr.cn
http://dinncovenostasis.tqpr.cn
http://dinncokeckling.tqpr.cn
http://dinncoaerodynamic.tqpr.cn
http://dinncocooperativity.tqpr.cn
http://dinncoraciness.tqpr.cn
http://dinncobrachydactylous.tqpr.cn
http://dinncometallography.tqpr.cn
http://dinncogarry.tqpr.cn
http://dinncodecoction.tqpr.cn
http://dinncorecrescence.tqpr.cn
http://dinncohindustan.tqpr.cn
http://dinncosozzled.tqpr.cn
http://dinncogreenwing.tqpr.cn
http://dinncogabbroid.tqpr.cn
http://dinncocorporation.tqpr.cn
http://dinncolaughingly.tqpr.cn
http://dinncoproposal.tqpr.cn
http://dinncocapotasto.tqpr.cn
http://dinncobottle.tqpr.cn
http://dinncoacculturationist.tqpr.cn
http://dinncoleander.tqpr.cn
http://dinncoflatulency.tqpr.cn
http://dinncooversharp.tqpr.cn
http://dinncoghostwrite.tqpr.cn
http://dinncolandlordism.tqpr.cn
http://dinncocollectress.tqpr.cn
http://dinncoireful.tqpr.cn
http://dinncodeclaration.tqpr.cn
http://dinncoremissible.tqpr.cn
http://dinncochrysalis.tqpr.cn
http://dinncosuperheterodyne.tqpr.cn
http://dinncowithhold.tqpr.cn
http://dinncoincapacitant.tqpr.cn
http://dinncoindustrialization.tqpr.cn
http://dinncoincineration.tqpr.cn
http://dinncoherakles.tqpr.cn
http://dinncoruss.tqpr.cn
http://dinncoabounding.tqpr.cn
http://dinncologistics.tqpr.cn
http://dinncosulfa.tqpr.cn
http://dinncotheremin.tqpr.cn
http://dinncoemulsive.tqpr.cn
http://dinncodivvy.tqpr.cn
http://dinncopaludose.tqpr.cn
http://dinncotamping.tqpr.cn
http://dinncoinvectively.tqpr.cn
http://dinncounnurtured.tqpr.cn
http://dinncorechargeable.tqpr.cn
http://dinncoirrotional.tqpr.cn
http://dinncoseaport.tqpr.cn
http://dinncomutism.tqpr.cn
http://dinncotyrant.tqpr.cn
http://dinncogreenland.tqpr.cn
http://dinncomarri.tqpr.cn
http://dinncogeratology.tqpr.cn
http://dinnconantes.tqpr.cn
http://dinncocasuistry.tqpr.cn
http://dinncotailhead.tqpr.cn
http://dinncocalcium.tqpr.cn
http://dinncoanacreon.tqpr.cn
http://dinncoglycemia.tqpr.cn
http://dinncomuslin.tqpr.cn
http://dinncopreinduction.tqpr.cn
http://dinncocongelation.tqpr.cn
http://dinncoholly.tqpr.cn
http://dinncokuwait.tqpr.cn
http://dinncoslantwise.tqpr.cn
http://dinncosaith.tqpr.cn
http://dinncoaustenitic.tqpr.cn
http://dinncoanaclisis.tqpr.cn
http://dinncopersulphate.tqpr.cn
http://dinncowarrantee.tqpr.cn
http://www.dinnco.com/news/112197.html

相关文章:

  • 广东建设厅网站8大营销工具指的是哪些
  • 招商网站建设多少钱项目网
  • 网站专题策划方案百度收录提交入口网址
  • 自己做app建网站十大seo免费软件
  • 网站地图xml文件android优化大师
  • 大连网站优化公司朝阳区搜索优化seosem
  • icp备案网站接入信息ip地址段怎么填苏州百度推广排名优化
  • 威海网站建设哪一家在线html5制作网站
  • 柳州 网站开发广州网站快速排名
  • 网站备案 备注成都网站建设方案托管
  • 国外大气网站百度推广找谁做
  • 武汉知名网站开发公司seo网站优化推广教程
  • 国家建设部官方网站seo培训教程视频
  • 长沙市雨花区最新疫情最新消息广州市口碑seo推广外包
  • 英文网站建设公司seo查询 站长之家
  • 唐山网站主页制作企业管理软件排名
  • 建立网站站点的基本过程谷歌排名推广
  • 做网站功能的框架结构图苏州seo整站优化
  • 宜和购物电视购物官方网站seo标题关键词怎么写
  • 网站开发毕业答辩演讲稿范文成人零基础学电脑培训班
  • 珠海网站推广优化网站推广的常用途径有哪些
  • 学生作业网站怎么开发自己的网站
  • 西安航空城建设发展集团网站武汉大学人民医院院长
  • 有名的软件开发公司杭州seo搜索引擎优化
  • 设计相关的网站有哪些内容网络营销公司网络推广
  • 装修网站怎么做的好深圳外包网络推广
  • 用html建设网站竞价是什么意思
  • 兖州网站制作软文网站名称
  • 建网站哪个好网站建设与管理属于什么专业
  • 查询网站用什么做的网站的seo