Shell 命令行动画制作

Shell 命令行动画制作

By Nodejs, 建议,拿对比度高的视频去制作,效果更好

  1. 视频转图片

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 安装 ffmpeg ()
    brew install ffmpeg

    ## 检测是否安装 ffmpeg
    ffmpeg -h

    # ffmpeg -i 视频路径[也可以是绝对路径] -r 帧数 输出图片路径
    ffmpeg -i ./assets/60f1bcc6321e9fda43c173c84b0391.mp4 -r 15 ./assets/images/%d.png

  2. 转化步骤
    完整源码里已经标注步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const fs = require("fs");
const { join, extname } = require("path");
const { read, intToRGBA } = require("jimp");
const { echo, exit } = require("shelljs");

const floder = join(__dirname, "./assets/images/");

// 如果画面对比度叫高,推荐使用 const charts = `##### `
// 构成字符: 颜色由 深到浅, 也可以增加符号
const charts = `@&$%=+!^*~- `;

const maxIndex = charts.length - 1;
const limitIndex = (num) => (num > maxIndex ? maxIndex : num);

fs.readdir(floder, undefined, (err, data) => {
if (err) throw err;

// 6. 过滤非 png 并排序
const files = data.filter((url) => extname(url) === ".png");
files.sort((a, b) => parseInt(a) - parseInt(b));

// 7. 递归播放
play(files);
});

const play = (files) => {
const printFileName = files.shift();

print(printFileName);

if (files.length) {
setTimeout(() => {
play(files);
// ps: 在 js 中 时间函数不可使用 小数 或 负数,否则会立即执行
}, parseInt(1000 / 15)); // 15 取决于 ffmpeg 分割的帧数

return;
}
exit(1);
};

const print = (fileName) => {
let subCharts = "";

// 1. 读取图片
const fileURL = join(floder, fileName);

read(fileURL).then((image) => {
// 2 获取宽高 ps: 方法不可结构,会报错
const width = image.getWidth();
const height = image.getHeight();

// 6. 调整合适的缩放比例 很重要
const xScale = width / 220;
const yScale = height / 40;

for (let y = 0; y < height; y += yScale) {
for (let x = 0; x < width; x += xScale) {
const { r, g, b } = intToRGBA(image.getPixelColor(x, y));

// 3. 读取像素点 的 灰度值
const gray = (0.3 * r + 0.59 * g + 0.11 * b).toFixed(2);

// 4. 算出灰度值在 charts 中表达的位置
const grayScale = parseFloat(gray / 255).toFixed(2);
const grayDegree = parseInt(grayScale * charts.length);
// +0.5 感觉更亮些
const index = Math.floor(limitIndex(grayDegree + 0.5));

// 5. 拼接
subCharts += charts[index];
}
subCharts += "\n";
}

echo(subCharts);
});
};
  1. 素材链接

  2. 感谢 大佬 提供 go 版本的教程

作者

Huasun47

发布于

2021-04-25

更新于

2021-04-25

许可协议