c++读取图片_「密恐慎入」制作字符画——把想说的话藏在图片里

制作目标

给定一张图片,编写程序,使用我们输入的字符,填充得到一张新的图片。具有表白斗图制作壁纸等多种用途。

639b40a4bbcd4573a167a94118fff7ea

效果预览

b759c5a5597347d9a61d15dae44fd2bf

效果预览

其他作品可见我的微头条:链接地址

制作环境

本教程为Windows环境下,使用Python 3.8.0,以及Pillow模块制作。 Pillow模块可以使用pip在线下载安装,优点是不需要选择版本,但容易因网络问题安装失败。也可在网页 https://pypi.org/project/Pillow/4.0.0/#files 选择合适版本下载后离线安装 ,优点是稳定,但下载速度比较慢。

制作原理

首先我们需要知道,图片是由像素点构成,每个像素点都有一个RGB(红绿蓝)值,常被写成(R,G,B)的形式。我们对图片进行处理时实质是对像素点进行处理。像素可以看成是图片里连续排列且带颜色的小方格,密密麻麻的像素才构成了一张张多姿多彩的图片。 那么要制作字符画,最直接的方法是将像素直接转换成字符,然后在一张同样大小的画布上写下文字。如下图所示

a8aec3b7187043b386a23a3a8cc68f86

将像素转换为文字

这种情况下虽然简单,但像素是非常小的,所以在生成图像后会看不清文字。而为看清文字,可以将画布扩增一下,得到下面的效果:

45f9ac40bd6b4b83a164058fb0ba49c3

将画布扩大一倍

通过这种方法,理论上只要倍数足够大,就可以看清图片上的文字,而又不破坏图片的清晰程度。但当将输出图片扩充得过大时,图片的占用的存储空间也会增大,发送接收耗时长,而且大部分软件都有图片大小限制吗,不适合作为表情包发送。

81872ad97cc645f38006c95ae3cbd68f

左:程序输出结果,右:原图,扩大8倍后输出图片所占空间是原图的304倍(四舍五入后)

这种情况下,对方法做进一步改进,在读取原图像素时,可以跳跃性的选择像素,如下图:

e38b427e59d04bba854d9e1966a1f744

跳跃选取与图片倍增后,可使显示的字符更大

通过这一方法,可以控制输出图片的大小。因为舍弃了原图部分像素,会导致输出图片的精细程度稍微不如原图。通过测试,发现汉字字号取值为[画布扩展倍数]*[像素抽取间隔]+1,这意味着想达到字号为9时,如果不设置像素抽取间隔,则图片尺寸会放大8倍,而设置了像素抽取间隔为2后,只需扩大4倍,这样可以有效减少空间占用。最后,由于文字不同于像素,文字之间存在间隙,所以画布的背景颜色会体现出来。

以上为制作字符画的思路,感兴趣的小伙伴可以私聊作者帮忙制作。接下来带来的是Python编程内容,有这方面能力的小伙伴们可以先尝试自行编程实现。


#首先要导入模块,这里只需导入PIL模块,这里我只需要PIL模块里的 Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont#创建几个变量保存图片名、填入字符、画布扩大倍数、像素点间隔filename = "[图片名]" s = "[填入的字符]" step = [画布扩展倍数] l = [像素间隔] #将填入字符拆分开 t = list(s) #设置画布的背景色(r,g,b)以及透明度(a),a=255时为不透明 r = 255 g = 255 b = 255 a = 255#打开原图,获得全部像素点,读取图片得长宽。simg = Image.open(filename) simg_array = simg.load() w,h = simg.size#选择填充到画布上的字体以及字号,字体可在C:WindowsFonts下找到,字号推荐设置为[画布扩展倍数]*[像素间隔] + 1 ttfont = ImageFont.truetype("‪C:WindowsFontssimfang.ttf",step*l + 1)  #创建画布 timg = Image.new('RGBA', (step*w, step*h), (r, g, b, a))  #进行绘制,读取原图像素,并在画布上使用对应颜色添加文字draw = ImageDraw.Draw(timg) start = 0 for i in range(0, h, l):     pos = start % len(t)     start += 1        for j in range(0, w, l):                     draw.text((j*step,i*step), t[pos%len(t)], simg_array[j,i], font = ttfont)            pos += 1 #打开图片预览,并保存 timg.show() timg.save("result.png")

以上为字符画制作的全部内容,感谢观看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思是利用已知信息来避免不必要的字符比较。具体来,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思。假设文本串为S="ababababca",模式串为P="abababca",我们要在S中查找P的现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P现在S的第二个位置。 下面是KMP算法的C++代码实现:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值