倾斜文字水印视频

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace StHH
{
    public class VideoHelper
    {
        //引用示例
        //VideoHelper.Install.ExecuteVideo(
        //       ffmpegPath: @"D:\app\ffmpeg\bin\ffmpeg.exe",
        //        originalVideo: @"D:\AreYouOk\AA.mp4",
        //        newVideo: @"D:\AreYouOk\newFile.mp4",
        //        waterWord:"少年强",
        //        fontSize: 18);

        public static readonly VideoHelper Install = new VideoHelper();

        /// <summary>
        /// 执行一条command命令
        /// </summary>
        /// <param name="command">需要执行的Command</param>
        /// <param name="output">输出</param>
        /// <param name="error">错误</param>
        private void ExecuteCommand(string command, out string output, out string error)
        {
            try
            {
                //创建一个进程
                Process pc = new Process();
                pc.StartInfo.FileName = command;
                pc.StartInfo.UseShellExecute = false;
                pc.StartInfo.RedirectStandardOutput = true;
                pc.StartInfo.RedirectStandardError = true;
                pc.StartInfo.CreateNoWindow = true;
                //启动进程
                pc.Start();

                //准备读出输出流和错误流
                string outputData = string.Empty;
                string errorData = string.Empty;
                pc.BeginOutputReadLine();
                pc.BeginErrorReadLine();

                pc.OutputDataReceived += (ss, ee) =>
                {
                    outputData += ee.Data;
                };

                pc.ErrorDataReceived += (ss, ee) =>
                {
                    errorData += ee.Data;
                };

                //等待退出
                pc.WaitForExit();

                //关闭进程
                pc.Close();

                //返回流结果
                output = outputData;
                error = errorData;
            }
            catch (Exception)
            {
                output = null;
                error = null;
            }
        }

        /// <summary>
        /// 获取视频的帧宽度和帧高度
        /// </summary>
        /// <param name="videoFilePath">mov文件的路径</param>
        /// <returns>null表示获取宽度或高度失败</returns>
        private void GetVideoSize(string videoFilePath, out int? width, out int? height)
        {
            try
            {
                //判断文件是否存在
                if (!File.Exists(videoFilePath))
                {
                    width = null;
                    height = null;
                }

                string ffmpegPath = FFmpegPath;
                string output;
                string error;
                ExecuteCommand("\"" + ffmpegPath + "\"" + " -i " + "\"" + videoFilePath + "\"", out output, out error);
                if (string.IsNullOrEmpty(error))
                {
                    width = null;
                    height = null;
                }

                //通过正则表达式获取信息里面的宽度信息
                Regex regex = new Regex("(\\d{2,4})x(\\d{2,4})", RegexOptions.Compiled);
                Match m = regex.Match(error);
                if (m.Success)
                {
                    width = int.Parse(m.Groups[1].Value);
                    height = int.Parse(m.Groups[2].Value);
                }
                else
                {
                    width = null;
                    height = null;
                }
            }
            catch (Exception)
            {
                width = null;
                height = null;
            }
        }

        /// <summary>
            /// 生成文字水印的图片
            /// </summary>
            /// <param name="text"></param>
            /// <param name="isBold"></param>
            /// <param name="fontSize"></param>
        private Image CreateWaterImage(string text, int fontSize, double w, double h)
        {
            Font font = new Font("宋体", fontSize, FontStyle.Regular);
            //绘笔颜色
            SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 255, 255));
            StringFormat format = new StringFormat(StringFormatFlags.NoClip);
            Bitmap image = new Bitmap(Convert.ToInt32(w), Convert.ToInt32(h));
            Graphics g = Graphics.FromImage(image);
            SizeF sizef = g.MeasureString(text, font, PointF.Empty, format);//得到文本的宽高
            int width = (int)(sizef.Width + 1);
            int height = (int)(sizef.Height + 1);

            int s_w = 1, s_h = 1;
            if (w > 100)
            {
                s_w = Convert.ToInt32(w / 100);
            }
            if (h > 100)
            {
                s_h = Convert.ToInt32(h / 100);
            }

            for (int x = 0; x < 1000; x++)
            {
                for (int y = 0; y < 1000; y++)
                {
                    float i_x = (float)(x * (width + w / s_w));
                    float i_y = (float)(y * (height + h / s_h));
                    if (i_x > w) continue;
                    if (i_y > h) continue;
                    RectangleF rect = new RectangleF(i_x, i_y, width, height);
                    //绘制图片
                    g.DrawString(text, font, brush, rect);
                }
            }
            //g.Clear(Color.Transparent);
            //g.Flush();
            //释放对象
            g.Dispose();
            return image;
        }
        /// <summary>
        /// 生成文字水印视频
        /// </summary>
        /// <param name="ffmpegPath">ffmpeg.exe路径</param>
        /// <param name="originalVideo">原始视频</param>
        /// <param name="newVideo">目标视频</param>
        /// <param name="waterWord">水印文字</param>
        /// <param name="fontSize">水印文字字体大小</param>
        /// <returns></returns>
        public VideoResult ExecuteVideo(string ffmpegPath, string originalVideo, string newVideo, string waterWord, int fontSize = 18)
        {
            FFmpegPath = ffmpegPath;
            VideoResult result = new VideoResult()
            {
                IsSuccess = false
            };
            if (string.IsNullOrEmpty(ffmpegPath))
            {
                result.Msg = "FFmpeg路径为空";
                return result;
            }
            if (string.IsNullOrEmpty(originalVideo))
            {
                result.Msg = "原始视频为空";
                return result;
            }
            if (File.Exists(originalVideo) == false)
            {
                result.Msg = "原始视频不存在";
                return result;
            }
            if (string.IsNullOrEmpty(newVideo))
            {
                result.Msg = "目标视频为空";
                return result;
            }
            if (string.IsNullOrEmpty(waterWord))
            {
                result.Msg = "水印文字为空";
                return result;
            }

            try
            {
                int? s_w, s_h;
                GetVideoSize(originalVideo, out s_w, out s_h);
                if (s_w.HasValue == false)
                {
                    result.Msg = "无法读取视频宽度";
                    return result;
                }
                if (s_h.HasValue == false)
                {
                    result.Msg = "无法读取视频高度";
                    return result;
                }
                if (s_w.Value <= 0)
                {
                    result.Msg = "无法识别视频宽度";
                    return result;
                }
                if (s_h.Value <= 0)
                {
                    result.Msg = "无法识别视频高度";
                    return result;
                }

                var i_w = Math.Sqrt(Math.Pow(s_w.Value, 2) + Math.Pow(s_h.Value, 2));
                var i_h = s_w.Value * s_h.Value * 2 / i_w;
                if (s_h.Value > s_w.Value)
                {
                    i_h = Math.Sqrt(Math.Pow(s_w.Value, 2) + Math.Pow(s_h.Value, 2));
                    i_w = s_w.Value * s_h.Value * 2 / i_h;
                }
                i_w = i_w * 1.2;
                i_h = i_h * 1.2;

                var v_x = (s_w - i_w) / 2;
                var v_y = (s_h - i_h) / 2;

                string watermarkImage = Path.Combine(System.Environment.CurrentDirectory, DateTime.Now.ToString("HHmmssfff") + ".png");
                Image img = CreateWaterImage(text: waterWord, fontSize: fontSize, i_w, i_h);
                img.Save(watermarkImage);
                img.Dispose();

                watermarkImage = watermarkImage.Substring(0, 1) + @"\\" + watermarkImage.Substring(1).Replace("\\", "/");
                //lut=a=val*0.15  调水印图片的透明度
                string arguments = "-i " + originalVideo + " -vf \"movie=" + watermarkImage + ",scale=w=" + i_w + ":h=" + i_h + ",rotate=a=-PI*30/180, lut=a=val*0.15[watermark];[in][watermark] overlay=x=" + v_x + ":y=" + v_y + "\"  " + newVideo;
                using (var process = new Process())
                {
                    process.StartInfo.FileName = FFmpegPath;
                    process.StartInfo.Arguments = arguments;
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.RedirectStandardOutput = true;
                    process.StartInfo.CreateNoWindow = true;
                    process.Start();
                    process.WaitForExit();
                }
                result.IsSuccess = true;
                return result;
            }
            catch (Exception ex)
            {
                result.Msg = "生成水印视频失败," + ex.Message;
                result.Ex = ex;
                return result;
            }
        }
        /// <summary>
        /// ffmpeg.exe路径
        /// </summary>
        private string FFmpegPath { get; set; }


    }
    public class VideoResult
    {
        public bool IsSuccess { get; set; } = false;

        public string Msg { get; set; } = "";

        public Exception Ex { get; set; }
    }
}

C#满屏倾斜文字水印的视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值