码区不大,创造神话,科目三杀进来了

前言

作为 Go 后端的唯一妹纸实习生,Boss 听说我之前跳过舞,实习第一天让我跳个程序员版本科目三,帮忙宣传一波,00 后整顿职场不能怂,被我义正严辞地拒绝了。

图片

图片

没想到过了一个小时,老板发了个红包。

图片

人间疾苦,有钱无阻,老板,你看人真准。自己跳是不可能的,咱来个“曲线救国”让 Excel 替我跳一个科目三。

图片

如何实现让 Excel 跳科目三呢?经过一番秃头研究👨‍🦲,想到视频都是由连续的图片组成,想要实现在 Excel 中跳舞那就需要多张连续的图片,只要找一个科目三舞蹈视频通过转换为连续的图片并将图片导入 Excel ,然后使用 Chromeless 截取个几百张图最后组装就能生成舞蹈视频啦。

图片

但是只插入图片未免太过无趣,网上搜罗一圈发现图片还能转 ASCII 字符集,且导入 Excel 方案可行,这就开干!

图片

视频转图片

首先是保存一个科目三的舞蹈视频,这里从各大视频网站中可以获取。从 Chrome 应用商店里白嫖一个下载插件,再白嫖一个科目三视频。

图片

最后,使用 ffmpeg 这个强大的视频流处理工具来获取指定帧数的图片。

官网下载地址:https://ffmpeg.org/download.html

从目标.mp4 视频文件中提取图像帧,每秒提取 15 帧,输出的图像文件名格式为三位数字.jpg

ffmpeg -i 目标.mp4 -r 15 %3d.jpg

运行结果如下:

图片

图片转 ASCII 字符集

重头戏之一来了,在线的转换工具倒是有不少,效果也不错👇

在线转换网站地址:https://neucrack.com/tools/ascii

图片

但是一秒的视频至少 15 张图片,十秒就是 150 张一个一个手动转换和手动导入 Excel 会夭寿的。

作为计算机专业出身,代码编写少不了,使用 Go 语言实现以上功能,流程图如下:

图片

这里使用广泛使用的 "github.com/fogleman/gg" 和 "github.com/nfnt/resize" 图形处理库来进行图片的缩放以及像素获取

func processPixel(context *gg.Context, file *excelize.File, h, w int) {    //获取像素点颜色    pixelColor := context.Image().At(w, h)    r, g, b, _ := pixelColor.RGBA()    //获取像素点亮度值    pixelValue, _, _ := color.RGBToYCbCr(uint8(r/256), uint8(g/256), uint8(b/256))    asciiIndex := int((float64(pixelValue) / 255) * float64(len(asciiChars)-1))    asciiChar := string(asciiChars[asciiIndex])    weight := asciiWeights[asciiIndex]    fontColor := fmt.Sprintf("%02X%02X%02X", int(r/256), int(g/256), int(b/256))    result := strings.Repeat(asciiChar, int(weight))    cell := fmt.Sprintf("%s%d", columnIndexToExcelName(w), h+1)    file.SetCellValue(sheetName, cell, result)    style, _ := file.NewStyle(&excelize.Style{       Font: &excelize.Font{          Color: fontColor, //字体颜色       },       Border: []excelize.Border{}, //空切片无边框    })    file.SetCellStyle(sheetName, cell, cell, style)}

映射方法:

在 RGB 色彩模型中,亮度的取值通常与颜色的亮度成正比。在这里,pixelValue 是从图像中提取的像素的亮度值。对于 RGB 色彩模型,可以通过以下公式将 RGB 值转换为亮度值:亮度值=0.299×R+0.587×G+0.114×B

这里,R、G、B 分别是像素的红、绿、蓝分量。这个公式是一种常见的计算灰度值的方法,其中每个颜色分量的权重反映了人眼对不同颜色的感知。在这种情况下,亮度值的范围通常是 [0, 255],其中 0 表示黑色,255 表示白色。

通常情况下,亮度值越大,表示像素的颜色越接近白色,亮度越小,表示颜色越接近黑色。在上述代码中,pixelValue 的值被归一化到范围 [0, 1],用于确定在 ASCII 字符集中选择哪个字符。

例如,根据自定义的 ASCII 字符集和权重:

-asciiChars="@%#*+=-" -weights="15,10,7,5,3,2,1"

亮度越大的值归一化后越接近 1,对应的字符索引越大,亮度越小的值归一化后越接近 0,对应的字符索引越小,255 白色亮度对应索引 index=len(asciiChars)-1 即转换后显示 1 个-字符,0 亮度黑色对应索引 index=0 即转换后显示 15 个@字符。

ASCII 字符集导入 Excel

这里使用 github.com/xuri/excelize/v2 库来进行 Excel 处理,进行单元格行列高列宽设置,单元格内容填充,并行处理像素点,最后保存 Excel 文件。

func imageToASCII(imagePath, outputExcel string) {    context, err := openAndResizeImage(imagePath, scaleFactor)    if err != nil {       fmt.Println(err)       return    }    //获取像素大小    imgWidth, imgHeight := context.Image().Bounds().Dx(), context.Image().Bounds().Dy()    file, _, err := createExcelFile()    if err != nil {       fmt.Println(err)       return    }    //设置单元格大小    setColumnWidths(file, imgWidth)    setRowHeights(file, imgHeight)    for h := 0; h < imgHeight; h++ {       wg.Add(1)       //并行处理每行像素点       go func(h int) {          defer wg.Done()          for w := 0; w < imgWidth; w++ {             processPixel(context, file, h, w)          }       }(h)    }    // 等待所有 goroutine 完成    wg.Wait()    // 保存 Excel 文件    if err := file.SaveAs(outputExcel); err != nil {       fmt.Println("Error saving Excel file:", err)    } else {       fmt.Println("Excel file saved")    }}

运行示例

  1. 以默认设置启动

图片

图片

图片

  1. 通过命令行参数自定义运行

参数解释如下图:go run ascii.go -h

图片

go run ascii.go -asciiChars="@%#*+=-:." -weights="15,10,7,5,3,2,1,0.5,0.1" 

图片

图片转视频

用程序将 excel 导入到石墨文档,在使用 chromedp 截图,最终使用 ffmpeg 转为每秒 15 帧的视频,然后播放,大功告成!

ffmpeg -r 15 -pattern_type glob -i '截屏*.png' video1.mp4

图片

播放:ffplay video1.mp4

图片

总结

到此,介绍了利用 Go 语言和一些开源库实现的一个有趣项目,通过将图片转换为 ASCII 字符,并将结果保存到 Excel 文件中,最终实现 Excel 版科目三视频。支持自定义字符集和权重以及图片缩放大小来实现不同的视觉效果。同时项目的不足之处在于处理大型图片时性能可能较差,可以考虑优化算法或者优化并行处理,后续也可以支持选择不同的图片转换方式,例如像素图等。希望通过分享这个项目,能够激发更多人对图形处理和代码创意的兴趣。

最后附上参考资料以及完整的源码地址:

  • 完整的源码:https://github.com/shimo-open/ascii-to-excel

  • fogleman/gg官方文档:https://pkg.go.dev/github.com/fogleman/gg

  • github地址:https://github.com/qax-os/excelize 

  • ffmpeg官网下载:https://ffmpeg.org/download.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值