使用ffmpeg 的 filter 给图片添加水印。
main.c

#include <stdio.h>#include <libavfilter/avfilter.h>
#include <libavfilter/buffersrc.h>
#include <libavfilter/buffersink.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>AVFilterContext* mainsrc_ctx = NULL;
AVFilterContext* logosrc_ctx = NULL;
AVFilterContext* resultsink_ctx = NULL;
AVFilterGraph* filter_graph = NULL;//初始化过滤器处理
static int init_filters(const AVFrame* main_frame, const AVFrame* logo_frame, int x, int y)
{int ret = 0;AVFilterInOut* inputs = NULL;AVFilterInOut* outputs = NULL;char filter_args[1024] = {0};//初始化用于整个过滤处理的封装filter_graph = avfilter_graph_alloc();if(!filter_graph){printf("%d : avfilter_graph_alloc() failed!\n", __LINE__);return -1;}//所有使用到过滤器处理的命令snprintf(filter_args, sizeof(filter_args),"buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/25:pixel_aspect=%d/%d[main];" // Parsed_buffer_0"buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/25:pixel_aspect=%d/%d[logo];" // Parsed_bufer_1"[main][logo]overlay=%d:%d[result];" // Parsed_overlay_2"[result]buffersink", // Parsed_buffer_sink_3main_frame->width, main_frame->height, main_frame->format, main_frame->sample_aspect_ratio.num, main_frame->sample_aspect_ratio.den,logo_frame->width, logo_frame->height, logo_frame->format, logo_frame->sample_aspect_ratio.num, logo_frame->sample_aspect_ratio.den,x, y);//添加过滤器处理到AVFilterGraphret = avfilter_graph_parse2(filter_graph, filter_args, &inputs, &outputs);if(ret < 0){printf("%d : avfilter_graph_parse2() failed!\n", __LINE__);return ret;}//配置AVFilterGraph的过滤器处理ret = avfilter_graph_config(filter_graph, NULL);if(ret < 0){printf("%d : avfilter_graph_config() failed!\n", __LINE__);return ret;}//获取AVFilterGraph内的过滤器mainsrc_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffer_0");logosrc_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffer_1");resultsink_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffersink_3");avfilter_inout_free(&inputs);avfilter_inout_free(&outputs);return 0;
}//添加水印
static int main_mix_logo(AVFrame* main_frame, AVFrame* logo_frame, AVFrame *result_frame)
{int ret = 0;//添加主图ret = av_buffersrc_add_frame(mainsrc_ctx, main_frame);if(ret < 0)return ret;//添加logoret = av_buffersrc_add_frame(logosrc_ctx, logo_frame);if(ret < 0)return ret;//获取合成图ret = av_buffersink_get_frame(resultsink_ctx, result_frame);return ret;}static AVFrame* get_jpeg(const char* filename)
{int ret = 0;AVFormatContext* format_ctx = NULL;//打开文件if((ret = avformat_open_input(&format_ctx, filename, NULL, NULL)) != 0){printf("%d : avformat_open_input() failed!\n");return NULL;}//获取媒体文件信息avformat_find_stream_info(format_ctx, NULL);AVCodec* codec = NULL;AVCodecContext* codec_ctx = NULL;int video_stream_index = -1;//获取流video_stream_index = av_find_best_stream(format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);if(video_stream_index < 0)goto cleanup;codec_ctx = avcodec_alloc_context3(codec);//关联解码器上下文ret = avcodec_open2(codec_ctx, codec, NULL);if(ret < 0)goto cleanup;AVPacket pkt;av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;//从文件中读一帧ret = av_read_frame(format_ctx, &pkt);if(ret < 0)goto cleanup;//进行解码ret = avcodec_send_packet(codec_ctx, &pkt);if(ret < 0)goto cleanup;//AVFrame* frame = av_frame_alloc();ret = avcodec_receive_frame(codec_ctx, frame);if(ret < 0)av_frame_free(&frame);cleanup:if(format_ctx)avformat_close_input(&format_ctx);if(codec_ctx)avcodec_free_context(&codec_ctx);return frame;
}static int savejpeg(const char* filename, const AVFrame* frame)
{//查找相应编码器AVCodec* jpeg_codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);if(!jpeg_codec)return -1;AVCodecContext* jpeg_codec_ctx = avcodec_alloc_context3(jpeg_codec);if(!jpeg_codec_ctx)return -2;//设置jpeg相关参数jpeg_codec_ctx->pix_fmt = AV_PIX_FMT_YUVJ420P;jpeg_codec_ctx->width = frame->width;jpeg_codec_ctx->height = frame->height;jpeg_codec_ctx->time_base.num = 1;jpeg_codec_ctx->time_base.den = 25;jpeg_codec_ctx->framerate.num = 25;jpeg_codec_ctx->framerate.den = 1;AVDictionary* encoder_opts = NULL;//encoder_opts 为空就会分配内存的av_dict_set(&encoder_opts, "flags", "+qscale", 0);av_dict_set(&encoder_opts, "qmax", "2", 0);av_dict_set(&encoder_opts, "qmin", "2", 0);int ret = avcodec_open2(jpeg_codec_ctx, jpeg_codec, &encoder_opts);if(ret < 0){avcodec_free_context(&jpeg_codec_ctx);printf("%d : avcodec_open2() failed!\n");return -3;}av_dict_free(&encoder_opts);AVPacket pkt;av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;//编码ret = avcodec_send_frame(jpeg_codec_ctx, frame);if(ret < 0){avcodec_free_context(&jpeg_codec_ctx);printf("%d : avcodec_send_frame() failed!\n");return -4;}ret = 0;while(ret >= 0){//得到编码数据ret = avcodec_receive_packet(jpeg_codec_ctx, &pkt);if(ret == AVERROR(EAGAIN))continue;if(ret == AVERROR_EOF){ret = 0;break;}FILE* outfile = fopen(filename, "wb");if(!outfile){printf("%d : fopen() failed!\n");ret = -1;break;}//写入文件if(fwrite((char*)pkt.data, 1, pkt.size, outfile) == pkt.size){ret = 0;}else{printf("%d : fwrite failed!\n");ret = -1;}fclose(outfile);ret = 0;break;}avcodec_free_context(&jpeg_codec_ctx);return ret;
}int main()
{printf("Hello watermarkmix!\n");AVFrame *main_frame = get_jpeg("main.jpg");AVFrame *logo_frame = get_jpeg("logo.jpg");AVFrame* result_frame = av_frame_alloc();int ret = 0;if(ret = init_filters(main_frame, logo_frame, 100, 200) < 0) {printf("%d : init_filters failed\n", __LINE__);goto end;}if(main_mix_logo(main_frame, logo_frame, result_frame) < 0) {printf("%d : main_picture_mix_logo failed\n", __LINE__);goto end;}savejpeg("output.jpg", result_frame);
end:if(main_frame)av_frame_free(&main_frame);if(logo_frame)av_frame_free(&logo_frame);if(result_frame)av_frame_free(&result_frame);if(filter_graph)avfilter_graph_free(&filter_graph);printf("finish\n");printf("End watermarkmix!\n");return 0;
}

使用ffmpeg 的 filter 给图片添加水印相关推荐

  1. ffmpeg 给视频或者图片添加水印和马赛克的方法

    可以使用 FFmpeg 给视频或图片添加水印和马赛克.以下是具体方法: 添加水印 如果需要给视频添加水印,可以使用 overlay 滤镜.该滤镜将两个输入叠加在一起,即将视频和水印画面结合在一起.以下 ...

  2. 为网页中的图片添加水印的效果

    程序本来源于http://dev.csdn.net/develop/article/22/22096.shtm中lovered所写的程序,我把其中的一些我觉得不太好的加以了改进并且增加一些功能形成了该 ...

  3. html中实现添加水印的功能,JS模拟实现图片添加水印功能

    JS模拟实现图片添加水印功能 ======================================================== 今天看到网友发帖求助如果在图片上自动添加水印的功能,于是 ...

  4. ffmpeg的filter分析

    原文网址(转载请注明出处): (http://blog.csdn.net/newchenxf/article/details/51364105) 目录 目录 什么是ffmpeg filter 如何使用 ...

  5. uniapp制作水印相机给图片添加水印并且保存图片至本地

    uniapp保存文件的三种方式 文件主要分为两大类: 1.代码包文件:代码包文件指的是在项目目录中添加的文件. 2.本地文件:通过调用接口本地产生,或通过网络下载下来,存储到本地的文件. 其中本地文件 ...

  6. JS模拟实现图片添加水印功能

    JS模拟实现图片添加水印功能 ======================================================== 今天看到网友发帖求助如果在图片上自动添加水印的功能,于是 ...

  7. FFmpeg video filter FATE测试过程介绍

    FATE (FFmpeg Automated Testing Environment) 是FFmpeg社区开发的自动化测试框架,支持对FFmpeg API的测试,也支持对FFmpeg内部函数的测试.对 ...

  8. 分享几个用 Python 给图片添加水印的方法,简单实用

    作者 |俊欣 来源 |关于数据分析与可视化 今天来分享几种可以给图片添加水印的方法,都是十分的简单实用,大家在看了之后也可以私底下去自己试试,有些方法需要的代码量就比较少,有些方法需要的代码量就稍微多 ...

  9. php 怎么支持中文图片显示,给图片添加水印(支持中文)并生成缩略图_php

    // **************************************** // // 功能:给图片添加水印(支持中文)并生成缩略图 // 参数: $srcFile 图片文件名 // $d ...

最新文章

  1. 智能医疗?轻松实现!
  2. 三张图助您掌握OTN分层结构
  3. nginx日志模块及日志格式
  4. aspx-cs-dll :在部署后就让所有的aspx处于已经编译成dll的状态
  5. Docker镜像是什么,有什么用?
  6. python顺序结构实验设计_实验二 顺序结构程序设计(验证性实验)
  7. Linux安全移除U盘,Windows 10用户可以快速移除U盘
  8. bzoj4152 The Captain (dijkstra)
  9. Android之Menu动态改变文字
  10. TP5.x——update更新成功但是返回是0
  11. 《土豆荣耀》重构笔记(七)控制角色移动并添加音效
  12. endnote修改正文中参考文献标注_如何用endnote修改毕业论文后参考文献格式为毕业手册要求格式...
  13. 计算机操作系统32位,电脑操作系统中32位和64位到底有哪些区别
  14. Java工程师待遇怎么样?
  15. 嘟嘟牛mysql 密码_嘟嘟牛管家数据转化为万象、Pubwin的操作步骤
  16. 手机页面点击电话进入拨号界面---a链接的tel属性
  17. java数据类型最大值_Java 基本数据类型最大值极限和最小值极限
  18. PCF应用管理平台介绍(PCF Apps Manager)
  19. c语言-结构体实例笔记
  20. VMware虚拟机无法连接外网怎么解决

热门文章

  1. 高阶函数 实现sum(2)(3) 柯里化
  2. 如何用堆栈来保存和恢复滚动条位置
  3. Linux ifconfig 配置网络接口
  4. [转]我是如何走进黑客世界的?
  5. 【poj2464】树状数组
  6. 关于eclipse的indigo版中文注释时字体太小的问题(转)
  7. java连接oracle数据库 -- jdbc连接
  8. jQuery中关于Ajax的详解
  9. ashly理器4.8软件汉化版_AMD 处理器核心比英特尔多还更便宜?英特尔回应
  10. python qt快速入门_PyQt5快速入门(一)