@agpwhy
2022-07-09T08:13:19.000000Z
字数 2286
阅读 262
最近看到一个好玩的教程和大家分享。
https://cxy.rbind.io/post/2021/08/18/r-image-chars-gif/
讲的是如何用一张图片换成那种字符动画。类似这样:

【gif不知为何出问题了】
使用的包如下主要是magick和gganimate
这两个包之前在介绍新冠疫情可视化的时候也搞过,这个里面还是有很多能搞的。
library(magick)img = image_read("./gif.gif")dir.create("./逐帧")
其实用webp格式也可以的
然后转逐帧的图片。
for (i in 1:length(img)) {image_write(img[i], format = "png", paste0("./逐帧/", i, ".png"))}
image2chars = function(pathIn = '',pathOutTxt = NULL,pathOutImg = NULL,jpg_quality = 80,width = 100,chars = c('&', '#', 'w', 's', 'k', 'd', 't', 'j', 'i', '.', ' '),isColor = FALSE){# pathIn: 原始图片的路径,支持各种格式。# pathOutTxt: 字符文本的输出路径,默认与原始图片在同一文件夹下。# pathOutImg: 字符图片的输出路径,默认与原始图片在同一文件夹下。# jpg_quality: 字符图片的质量,范围0-100。# width: 字符文本的宽度,默认为100,即一行100个字符。# chars: 字符集,可自定义;# isColor: 字符图片是否为彩色,默认为黑白字符图片img = image_read(pathIn) # 读入图片gray = image_convert(img, colorspace = 'gray') # 转为灰度图rgb = image_convert(img, colorspace = 'rgb') # 转为rgb图# 修改图片尺寸gray = image_resize(gray, paste0(width, 'x'))rgb = image_resize(rgb, paste0(width, 'x'))# 获取图片灰度值矩阵,并将各像素值对应于相应字符gray = as.integer(image_data(gray))[, , 1]w = ncol(gray) # 图片宽度h = nrow(gray) # 图片高度index = findInterval(c(gray),seq(0, 255, length.out = length(chars) + 1),rightmost.closed = T)labels = chars[index]labels_mat = matrix(labels, ncol = w)# 输出字符文本,并保存成文件if(is.null(pathOutTxt))pathOutTxt <- paste0(gsub(".png", "", pathIn), ".txt")write.table(labels_mat, pathOutTxt, quote = F, row.names = F, col.names = F)# 绘制字符图片,给相应字符着色,并保存成文件if(isColor){rgb = as.integer(image_data(rgb))r = rgb[, , 1] # red通道像素矩阵g = rgb[, , 2] # green通道像素矩阵b = rgb[, , 3] # blue通道像素矩阵cols = rgb(c(r), c(g), c(b), maxColorValue = 255) # 转化为颜色表示}if(is.null(pathOutImg))pathOutImg = paste0(gsub(".png", "", pathIn), ".jpg")jpeg(pathOutImg, width = 16 * w, height = 16 * h, quality = jpg_quality)op = par(mar = c(0, 0, 0, 0))plot(0, xlab = '', ylab = '', asp = 1,xlim = c(0, w), ylim = c(0, h),xaxs = "i", yaxs = "i",type = 'n', axes = FALSE)grid = expand.grid(y = h:1 - 0.5, x = 1:w - 0.5) # 各字符位置if (isColor) {text(grid$x, grid$y, labels, cex = 1.5, col = cols) # 绘制彩色字符} else {text(grid$x, grid$y, labels, cex = 1.5) # 绘制黑白字符}par(op)dev.off()}
每帧图片都转成字符图
for (i in 1:length(img)) {pathIn = paste0("./逐帧/", i, ".png")image2chars(pathIn,width = 72,isColor = TRUE,chars = c('&', '#', 'w', 's', 'k', 'd', 't', 'j', 'i', '.', ' '))}
每帧都是这样

然后在使用gganimate把各帧结合成动图
library(gganimate)p = 1:length(img)animate_p = image_animate(image = image_read(path = paste0("./逐帧/", p, ".jpg")))anim_save(filename = "charnew.gif",animation = animate_p)

【gif不知为何出问题了】