Java ffmpeg 实现视频加文字/图片水印功能

打印 上一主题 下一主题

主题 832|帖子 832|积分 2496

引入依赖
  1. <dependency>
  2.   <groupId>org.bytedeco</groupId>
  3.   <artifactId>javacv-platform</artifactId>
  4.   <version>1.5.4</version>
  5. </dependency>
  6. <dependency>
  7.   <groupId>org.bytedeco</groupId>
  8.   <artifactId>ffmpeg-platform</artifactId>
  9.   <version>4.3.1-1.5.4</version>
  10. </dependency>
复制代码
代码示例

文字水印实现
  1. import org.bytedeco.javacv.*;
  2. import org.bytedeco.javacv.Frame;
  3. import java.awt.*;
  4. import java.awt.image.BufferedImage;
  5. /**
  6. * 视频添加文字水印
  7. *
  8. * @author alin
  9. */
  10. public class VideoWatermark {
  11.     public static void main(String[] args) throws Exception {
  12.         // 视频文件
  13.         String inputFile = "D:\\test\\video.mp4";
  14.         // 输出文件
  15.         String outputFile = "D:\\test\\output.mp4";
  16.         // 初始化FFmpegFrameGrabber以读取输入视频文件
  17.         try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile)) {
  18.             grabber.start();
  19.             // 初始化FFmpegFrameRecorder以写入输出视频文件
  20.             try (FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels())) {
  21.                 recorder.setFormat("mp4");
  22.                 recorder.setSampleRate(grabber.getSampleRate());
  23.                 recorder.setFrameRate(grabber.getFrameRate());
  24.                 recorder.setTimestamp(grabber.getTimestamp());
  25.                 recorder.setVideoBitrate(grabber.getVideoBitrate());
  26.                 recorder.setVideoCodec(grabber.getVideoCodec());
  27.                 recorder.start();
  28.                 // 处理每一帧
  29.                 Frame frame;
  30.                 Java2DFrameConverter converter = new Java2DFrameConverter();
  31.                 while ((frame = grabber.grab()) != null) {
  32.                     if (frame.image != null) {
  33.                         // 将Frame转换为BufferedImage
  34.                         BufferedImage bufferedImage = converter.getBufferedImage(frame);
  35.                         // 在BufferedImage上绘制文字水印
  36.                         Graphics2D g = bufferedImage.createGraphics();
  37.                         // 启用抗锯齿
  38.                         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  39.                         // 启用文本抗锯齿
  40.                         g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
  41.                         // 使用支持中文的字体
  42.                         g.setFont(new Font("Microsoft YaHei", Font.BOLD, 30));
  43.                         g.setColor(Color.gray);
  44.                         String watermarkText = "测试水印文字";
  45.                         // 计算水印文字的位置 右下角
  46.                         //FontMetrics fontMetrics = g.getFontMetrics();
  47.                         //int textWidth = fontMetrics.stringWidth(watermarkText);
  48.                         //int textHeight = fontMetrics.getHeight();
  49.                         //int x = bufferedImage.getWidth() - textWidth - 10; // 右边距10像素
  50.                         //int y = bufferedImage.getHeight() - textHeight + fontMetrics.getAscent() - 10; // 下边距10像素
  51.                         // 计算水印文字的位置 左上角
  52.                         int x = 10; // 左边距10像素
  53.                         int y = 30; // 上边距30像素
  54.                         g.drawString(watermarkText, x, y);
  55.                         g.dispose();
  56.                         // 将BufferedImage转换回Frame
  57.                         frame = converter.convert(bufferedImage);
  58.                     }
  59.                     // 记录帧
  60.                     recorder.record(frame);
  61.                 }
  62.                 // 关闭grabber和recorder
  63.                 recorder.stop();
  64.                 recorder.release();
  65.                 grabber.stop();
  66.             }
  67.         }
  68.     }
  69. }
复制代码
图片水印实现
  1. import org.bytedeco.javacv.*;
  2. import org.bytedeco.javacv.Frame;
  3. import javax.imageio.ImageIO;
  4. import java.awt.*;
  5. import java.awt.image.BufferedImage;
  6. import java.io.File;
  7. import java.io.IOException;
  8. import java.net.URL;
  9. /**
  10. * 视频添加图片水印
  11. *
  12. * @author alin
  13. */
  14. public class VideoWatermark {
  15.     public static void main(String[] args) throws Exception {
  16.         // 视频文件
  17.         String inputFile = "D:\\test\\video.mp4";
  18.         // 输出文件
  19.         String outputFile = "D:\\test\\output.mp4";
  20.         // 水印照片
  21.         String watermarkImageUrl = "D:\\test\\test.png";
  22.         try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile)) {
  23.             grabber.start();
  24.             try (FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels())) {
  25.                 recorder.setFormat("mp4");
  26.                 recorder.setSampleRate(grabber.getSampleRate());
  27.                 recorder.setFrameRate(grabber.getFrameRate());
  28.                 recorder.setTimestamp(grabber.getTimestamp());
  29.                 recorder.setVideoBitrate(grabber.getVideoBitrate());
  30.                 recorder.setVideoCodec(grabber.getVideoCodec());
  31.                 recorder.start();
  32.                 BufferedImage watermarkImage = loadWatermarkImage(watermarkImageUrl);
  33.                 Frame frame;
  34.                 while ((frame = grabber.grab()) != null) {
  35.                     if (frame.image != null) {
  36.                         Java2DFrameConverter converter = new Java2DFrameConverter();
  37.                         BufferedImage bufferedImage = converter.getBufferedImage(frame);
  38.                         // 在BufferedImage上绘制图片水印
  39.                         Graphics2D g = bufferedImage.createGraphics();
  40.                         g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
  41.                         int x = 10; // 左边距10像素
  42.                         int y = 30; // 上边距30像素
  43.                         g.drawImage(watermarkImage, x, y, null);
  44.                         g.dispose();
  45.                         frame = converter.convert(bufferedImage);
  46.                     }
  47.                     recorder.record(frame);
  48.                 }
  49.                 recorder.stop();
  50.                 recorder.release();
  51.                 grabber.stop();
  52.             }
  53.         }
  54.     }
  55.     /**
  56.      * 加载水印图片
  57.      *
  58.      * @param imagePath 水印图片路径
  59.      * @return 水印图片
  60.      * @throws IOException
  61.      */
  62.     private static BufferedImage loadWatermarkImage(String imagePath) throws IOException {
  63.         //return ImageIO.read(new URL(imagePath));
  64.         return ImageIO.read(new File(imagePath));
  65.     }
  66. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

灌篮少年

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表