介绍
这篇文章将为大家详细讲解有关利用Python实现一个将图片转换成字符画的国内,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
字符画是一种由字母,标点或其他字符组成的图画,它产生于互联网时代,在聊天软件中使用较多,本文我们看一下如何将自己喜欢的图片转成字符画。
<强>静态图片强>
首先,我们来演示将静态图片转为字符画,功能实现主要用到的Python库为OpenCV,安装使用pip安装opencv-python命令即可。
功能实现的基本思路为:利用聚类将像素信息聚为3或5类,颜色最深的一类用数字密集度表示,阴影的一类用横杠(-)表示,明亮部分用空白表示。
主要代码实现如下:
def img2strimg(帧,K=5): 如果类型(帧)!=np.ndarray:=np.array帧(帧) 高度、宽度、* _=frame.shape frame_gray=cv2。cv2.COLOR_BGR2GRAY cvtColor(框架) frame_array=np.float32 (frame_gray.reshape (1))=(cv2标准。TERM_CRITERIA_EPS + cv2。TERM_CRITERIA_MAX_ITER 10 1.0) 旗帜=cv2.KMEANS_RANDOM_CENTERS #得到标签(类别),重心(矩心) 密实度、标签质心=cv2。kmeans (frame_array, K,没有一个标准,10,旗帜) 质心=np.uint8(重心) #标签的数个矩心以随机顺序排列,所以需要简单处理矩心 质心=centroids.flatten () centroids_sorted=排序(重心) #获得不同形心的明暗程度,0为最暗 centroids_index=np.array ([centroids_sorted.index(价值)的价值重心)) 明亮=[abs ((3 * i - 2 * K)/(3 * K))我的范围(1,1 + K)) bright_bound=bright.index (np.min(明亮)) 影子=[abs ((3 * i - K)/(3 * K))我的范围(1,1 + K)) shadow_bound=shadow.index (np.min(影子)) 标签=labels.flatten () #将标签转变为实际的明暗程度列表=centroids_index标签(标签) #解析列表 labels_picked=[标签[*宽度:行(行数+ 1)*宽度:2]的行范围(0,高度,2)] 帆布=np。0(3 *高度,3 *宽度,3),np.uint8) #创建长宽为原图三倍的白色画布 canvas.fill (255) y=8 在labels_picked行: x=0 关口的行: 如果关口& lt;=shadow_bound: cv2。putText(画布,str(随机的。randint (2、9)), cv2 (x, y)。FONT_HERSHEY_PLAIN, 0.45, 1) elif关口& lt;=bright_bound: cv2。putText(画布,“产生绯闻,(x, y), cv2。FONT_HERSHEY_PLAIN, 0.4, 0,1) x +=6 y +=6 返回帆布
原图如下:
效果图如下:
<强> GIF动图强>
接下来我们演示将GIF转为字符画,功能实现主要用到的Python库为imageio,枕头,安装使用pip安装imageio/枕头命令即可。
功能实现的基本思路如下:
将GIF图片的每一帧拆分为静态图片
将所有静态图片变为字符画
将所有字符画重新合成GIF
主要代码实现如下:
#拆分gif将每一帧处理成字符画 def gif2pic(文件、ascii_chars isgray、字体、规模): & # 39;& # 39;& # 39; 文件:gif文件 ascii_chars:灰度值对应的字符串 isgray:是否黑白 字体:ImageFont对象 规模:缩放比例 & # 39;& # 39;& # 39; 我=Image.open(文件) 路径=os.getcwd () 如果(不是os.path.exists(+路径“/tmp")): os.mkdir(+路径“/tmp") os.chdir(+路径“/tmp") #清空tmp目录下内容 在os.listdir f(+路径“/tmp"): os.remove (f) 试一试: 而1: 当前=im.tell () name=file.split(& # 39;强生# 39;)[0]+ & # 39;_tmp_& # 39; + str(当前)+ & # 39;. png # 39; #保存每一帧图片 im.save(名字) #将每一帧处理为字符画 img2ascii(名称、ascii_chars isgray、字体、规模) #继续处理下一帧 im.seek(当前+ 1) 除了: os.chdir(路径) #将不同的灰度值映射为ASCII字符 def get_char (ascii_chars, r, g, b): 长度=len (ascii_chars) 灰色=int (0.2126 * r + 0.7152 * 0.0722 g + * b) 返回ascii_chars [int(灰色/(256/长度))) #将图片处理成字符画 def img2ascii (img ascii_chars isgray,字体、规模): 规模=规模 #将图片转换为RGB模式 我=Image.open (img) .convert (& # 39; rgb # 39;) #设定处理后的字符画大小 raw_width=int (im。宽度*规模) raw_height=int (im。高度*规模) #获取设定的字体的尺寸 font_x font_y=font.getsize (& # 39;& # 39;) #确定单元的大小 block_x=int (font_x *规模) block_y=int (font_y *规模) #确定长宽各有几个单元 w=int (raw_width/block_x) h=int (raw_height/block_y) #将每个单元缩小为一个像素 我=我。调整((w h), Image.NEAREST) # txt和颜色分别存储对应块的ASCII字符和RGB值 txt=[] 颜色=[] 因为我在范围(h): 行=& # 39;& # 39; lineColor=[] j的范围(w): 像素=我。获取像素((j,我)) lineColor。追加([0],像素扫描[1],像素[2])) 行+=get_char ([0] ascii_chars,像素,像素[1],像素[2]) txts.append(线) colors.append (lineColor) #创建新画布 img_txt=Image.new (& # 39; rgb # 39; (raw_width raw_height) (255、255、255)) #创建ImageDraw对象以写入ASCII 画=ImageDraw.Draw (img_txt) j的范围(len (txt)): 因为我在范围(len (txt [0])): 如果isgray: 画画。文本((我* block_x j * block_y), txt [j][我],(119136153)) 其他: 画画。文本((我* block_x j * block_y), txt [j][我],[j][我])颜色 img_txt.save (img) #读取tmp目录下文件合成gif def pic2gif (dir_name out_name,持续时间): 路径=os.getcwd () os.chdir (dir_name) dirs=os.listdir () 图像=[] num=0 在dirs: d images.append (imageio.imread (d)) num +=1 os.chdir(路径) imageio。null利用Python实现一个将图片转换成字符画的国内