图片转字符图片(三)
序言
这个是从抖音上学来的,一开始刷抖音,遇到不少字符串跳舞的视频,因此来实践一下
主要分为三个部分
- 静态图片转静态图片
- gif转gif
- 视频转视频
视频转视频
主要用到了FFmpeg这个工具,利用命令对视频文件进行操作。首先根据自己调的参数进行图片的截取(本文的是1秒10帧的参数),图片转换,然后分离音频,最后字符图片和音频合成目标视频。
FFmpeg的代码库:
https://github.com/FFmpeg/FFmpeg
FFmpeg下载地址:
https://ffmpeg.org/download.html
主要用到的几个命令,其他按帧截图命令参考文末链接4:
// 截图
ffmpeg -ss 10 -i input.flv -y -f image2 -vframes 100 -s 352x240 b-%03d.jpg
// 分离音频
ffmpeg -i 3.mp4 -vn -y -acodec copy 3.aac
// 合成视频
ffmpeg -threads2 -y -r 10 -i /tmpdir/image%04d.jpg -i audio.mp3 -absf aac_adtstoasc output.mp4
环境:
JDK 1.8
// ffmpeg -ss 10 -i input.flv -y -f image2 -vframes 100 -s 352x240 b-%03d.jpg
/**
* ffmpeg 截图,并指定图片的大小
*
* @param srcVideoPath
* @param tarImagePath
* 截取后图片路径
* @param width
* 截图的宽
* @param hight
* 截图的高
* @param offsetValue
* 表示相对于文件开始处的时间偏移值 可以是分秒
* @param vframes
* 表示截图的桢数
*
* @return
*/
public static boolean processFfmpegImage(String srcVideoPath, String tarImagePath, int width, int hight,
float offsetValue, float vframes) {
if (!checkfile(srcVideoPath)) {
System.out.println("【" + srcVideoPath + "】 不存在 !");
// logger.error("【" + srcVideoPath + "】 不存在 !");
return false;
}
List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-i");
commend.add(srcVideoPath);
commend.add("-y");
commend.add("-f");
commend.add("image2");
commend.add("-ss");
commend.add(offsetValue + ""); // 在视频的某个插入时间截图,例子为5秒后
// commend.add("-vframes");
commend.add("-t");// 添加参数"-t",该参数指定持续时间
commend.add(vframes + ""); // 截图的桢数,添加持续时间为1毫秒
commend.add("-s");
commend.add(width + "x" + hight); // 截图的的大小
commend.add(tarImagePath);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.redirectErrorStream(true);
// builder.redirectOutput(new File("F:/123/log/log.log"));
Process process = builder.start();
doWaitFor(process);
process.destroy();
if (!checkfile(tarImagePath)) {
System.out.println(tarImagePath + " is not exit! processFfmpegImage 转换不成功 !");
// logger.info(tarImagePath + " is not exit! processFfmpegImage
// 转换不成功 !");
return false;
}
return true;
} catch (Exception e) {
e.printStackTrace();
System.out.println("【" + srcVideoPath + "】 processFfmpegImage 转换不成功 !");
// logger.error("【" + srcVideoPath + "】 processFfmpegImage 转换不成功
// !");
return false;
}
}
public static boolean processFfmpegAudio(String srcVideoPath, String tarAudioPath) {
if (!checkfile(srcVideoPath)) {
System.out.println("【" + srcVideoPath + "】 不存在 !");
// logger.error("【" + srcVideoPath + "】 不存在 !");
return false;
}
// https://blog.csdn.net/xiaocao9903/article/details/53420519
// ffmpeg -i 3.mp4 -vn -y -acodec copy 3.aac
// ffmpeg -i 3.mp4 -vn -y -acodec copy 3.m4a
List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-i");
commend.add(srcVideoPath);
commend.add("-vn");
commend.add("-y");
commend.add("-acodec");
commend.add("copy"); // 在视频的某个插入时间截图,例子为5秒后
commend.add(tarAudioPath);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.redirectErrorStream(true);
Process process = builder.start();
doWaitFor(process);
process.destroy();
if (!checkfile(tarAudioPath)) {
System.out.println(tarAudioPath + " is not exit! processFfmpegAudio 转换不成功 !");
return false;
}
return true;
} catch (Exception e) {
e.printStackTrace();
System.out.println("【" + srcVideoPath + "】 processFfmpegAudio 转换不成功 !");
return false;
}
}
/**
* ffmpeg 合成视频
*
* @param srcVideoPath
* @param tarImagePath
* 截取后图片路径
* @param width
* 截图的宽
* @param hight
* 截图的高
* @param offsetValue
* 表示相对于文件开始处的时间偏移值 可以是分秒
* @param vframes
* 表示截图的桢数
*
* @return
*/
public static boolean processFfmpegVideo(String imagePath, String audioPath, String tarVideoPath, int step) {
// https://blog.csdn.net/wangshuainan/article/details/77914508?fps=1&locationNum=4
// 带音频
// ffmpeg -threads2 -y -r 10 -i /tmpdir/image%04d.jpg -i audio.mp3 -absf
// aac_adtstoasc output.mp4
List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-threads");
commend.add("2");
commend.add("-y");
commend.add("-r");
commend.add(step + "");
commend.add("-i");
commend.add(imagePath); // 图片
commend.add("-i");
commend.add(audioPath);
commend.add("-absf");//
commend.add("aac_adtstoasc"); //
commend.add(tarVideoPath);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.redirectErrorStream(true);
builder.redirectOutput(new File("F:/123/log/log.log"));
Process process = builder.start();
doWaitFor(process);
process.destroy();
if (!checkfile(tarVideoPath)) {
System.out.println(tarVideoPath + " is not exit! processFfmpegVideo 转换不成功 !");
return false;
}
return true;
} catch (Exception e) {
e.printStackTrace();
System.out.println("【" + tarVideoPath + "】 processFfmpegVideo 转换不成功 !");
return false;
}
}
源码地址:
https://github.com/Ruffianjiang/java4fun/tree/master/img2text
参考:

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
图片转字符图片(二)
序言 这个是从抖音上学来的,一开始刷抖音,遇到不少字符串跳舞的视频,因此来实践一下 主要分为三个部分 静态图片转静态图片 gif 转 gif 视频转视频 gif 转 gif 原理和静态图片的转换类似,这个需要每一帧的去转换。一开始的思路是把gif的每一帧转为图片,然后对图片进行转换,最后合成 gif 。 研究了 im4java,参考: https://blog.csdn.net/DamonRush/article/details/51746995、https://blog.csdn.net/weiwangchao_/article/details/46520571, 还有一些其他的工具(用了私有api,不推荐) http://zhaorui1125.iteye.com/blog/2116816, 最后发现他们截出来的每一张图要么发红,要么模糊,只好放弃了。最后发现不需要把每一帧都保存下来,临时存一下就好,具体代码如下: 环境: JDK 1.8 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; i...
-
下一篇
[雪峰磁针石博客]python代码风格指南(PEP8中文版)
本文给出主Python版本标准库的编码约定。CPython的C代码风格参见PEP7。 本文和PEP 257 文档字符串标准改编自Guido最初的《Python Style Guide》, 并增加了Barry的GNU Mailman Coding Style Guide的部分内容。 本文会随着语言改变等而改变。 许多项目都有自己的编码风格指南,冲突时自己的指南为准。 一致性考虑 Guido的关键点之一是:代码更多是用来读而不是写。本指南旨在改善Python代码的可读性,即PEP 20所说的“可读性计数"(Readability counts)。 风格指南强调一致性。项目、模块或函数保持一致都很重要。 最重要的是知道何时不一致, 有时风格指南并不适用。当有疑惑时运用你的最佳判断,参考其他例子并多问! 特别注意:不要因为遵守本PEP而破坏向后兼容性! 部分可以违背指南情况: 遵循指南会降低可读性。 与周围其他代码不一致。 代码在引入指南完成,暂时没有理由修改。 旧版本兼容。 代码布局 缩进 每级缩进用4个空格。 括号中使用垂直隐式缩进或使用悬挂缩进。后者应该注意第一行要没有参数,后续行要有缩...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- MySQL8.0.19开启GTID主从同步CentOS8
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装