package main
import (
"bytes"
"fmt"
"gocv.io/x/gocv"
"golang.org/x/crypto/ssh/terminal"
"image"
"os"
"os/exec"
"time"
)
const pixels = ` .,-'` + `:!1+*abcdefghijklmnopqrstuvwxyz<>()\/{}[]?234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ%&@#$`
func main() {
// 打开文件
c, err := gocv.VideoCaptureFile("../1.mp4")
// 获取帧数
fps := c.Get(gocv.VideoCaptureFPS)
if err != nil {
panic(err)
}
mat := gocv.NewMat()
w, h := 0, 0
// 放大缩小倍率
b := 0
// 每一帧之间时长
s := int64((1 / fps) * 1e6)
var t time.Time
// 每一帧时长与每一帧计算时长之差
var sub int64
var buf bytes.Buffer
// 转化大小
point := image.Point{Y: 0, X: 0}
for c.Read(&mat) {
t = time.Now()
// 获取终端大小
wl, hl, _ := terminal.GetSize(int(os.Stdout.Fd()))
// 如果终端大小发生变化则重新计算放大缩小倍率
if wl != w || hl != h {
w = wl
h = hl
x, y := mat.Rows(), mat.Cols()
if hl > wl {
if x < wl {
b = wl / x
x *= b
y *= b
} else {
b = x / wl
x /= b
y /= b
}
} else {
if y < hl {
b = hl / y
x *= b
y *= b
} else {
b = y / hl
x /= b
y /= b
}
}
point.X = x
point.Y = y
}
// 转灰度
gocv.CvtColor(mat, &mat, gocv.ColorBGRToGray)
// resize图像大小
gocv.Resize(mat, &mat, point, 0, 0, gocv.InterpolationLinear)
// 图像归一化
mat.DivideFloat(255 / float32(len(pixels)-1))
cols, rows := mat.Cols(), mat.Rows()
buf.Reset()
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
// 图像转化字符
buf.WriteByte(pixels[mat.GetSCharAt(i, j)])
}
buf.WriteByte('\n')
}
sub= time.Now().Sub(t).Microseconds()
// 如果比较计算时间与每一帧图像时间
if sub < s {
// 休眠,使字符显示时间靠近源视频每一帧时间
time.Sleep(time.Duration(s-sub) * time.Microsecond)
}
// 清屏
cmd := exec.Command("bash", "-c", "clear")
cmd.Stdout = os.Stdout
cmd.Run()
fmt.Print(buf.String())
}
}
Last modification:August 12, 2021
© Allow specification reprint
One comment
1
