美文网首页
随笔 | 一段有趣的代码

随笔 | 一段有趣的代码

作者: 0与1的邂逅 | 来源:发表于2020-02-16 15:51 被阅读0次

写在前面:

好久没有更新了,本来想着在2月14号发这篇随笔的,但是仔细想想,还是过两天再发比较合适,毕竟2月14号这个日期并不适合自己。

时针拨回两年前,那年我竟然要写一篇关于情人节的推送,内容涉及到情人节礼物等等,这对我来说简直就是 “难于上青天” 。结果可想而知,最后还是你亲自动手改我的推送,内容简直就是焕然一新,完全变了一个样。

再后来,你不再是我的 “上司”,见面的机会几乎没有。你依然躺在我的VX置顶,但是这又能说明什么呢。如果你要问有哪些英文单词让我记忆深刻,那么 bookstall 这个单词一定在其中。

上面的内容就当我是在胡扯吧,其实写这篇文章,可以说纯粹就是娱乐一下。在看了情人节来了,教你个用 Python 表白的技巧 & 这段 Python 代码,可以让你脱单 这两篇文章之后,感觉挺有意思的,自己也跟着试了一下。

1. 引入

PS:此小节的内容来源于 情人节来了,教你个用 Python 表白的技巧

前段时间,在微博上刷到了一条推荐。内容是这样的

出于好奇,我点开了,放大再放大,emmm,有点意思吖…(此处说明:需要 在手机上 查看才能看到效果)

2. 原理

PS:此小节的内容来源于 情人节来了,教你个用 Python 表白的技巧

接下来我们就来聊聊 情人节该怎么向ta表白 图片背后的原理。

事实上,每一张图片都是由一个一个的像素点所组成的。而每个像素点,都有自己的颜色,其颜色可以用一个数组来表示:(a,b,c),其中每位数的取值范围都是 0-255

比如 (0,0,0) 代表白色,(255,255,255) 代表黑色。

当像素点足够多的时候,这张照片就是我们所说的高清照片;而如果当像素点太少,我们的肉眼就能感知到明显的锯齿感(也就是我们所说的糊掉了)。

用 Excel 画了个图,每一方格代表一个像素,其中若我的字体的大小设置 5(非字号 5,而是每个字占用 5 个像素),效果大概就是如下这样子。

我只要 每个像素取出一个像素值,并使用这个像素做为该字的颜色即可,在像素量够多的情况下,从远处看,是能看到我们原来图像的轮廓的。

3. 实现

说完了原理,接下来我们尝试用 python 来实现。

PS:本小节的内容来源于 情人节来了,教你个用 Python 表白的技巧 & 这段 Python 代码,可以让你脱单

  • 首先,使用 pillow.Image 读取图像,并使用 load函数 获取图片的每一个像素值。
img_raw = Image.open(img_path)
img_array = img_raw.load()

  • 然后新建一张画布,并选好你要使用的字体和字体大小。

  • 我还增加了一个参数叫做 font\_space原来的代码 生成的字可能有点紧凑,这里我增加这个参数可以控制字和字的距离,比如 font\_space = 1,字间距就是字的大小,就是紧密排布的,如果改大一点,比如 font\_space = 1.2,字间距就会变成字的 1.2 倍,就留有字大小的 0.2 倍的空隙。(来源于 这段 Python 代码,可以让你脱单

# 字体大小
font_size = 7
# 字体间距,1 即间距正好为字体大小,紧凑排布,1.2 为字体大小的 1.2 倍
font_space = 1.2
# 字体文件的路径
font_file = 'C:/Windows/Fonts/Alibaba-PuHuiTi-Regular.ttf'

img_new = Image.new('RGB', img_raw.size, (0, 0, 0))
draw = ImageDraw.Draw(img_new)
font = ImageFont.truetype(font_file, size=font_size)

# 绘制的文本
text = '情人节快乐'

def character_generator(text):
    while True:
        for i in range(len(text)):
            yield text[i]

  • 接着,要给这些字加上相应的颜色,写入新创建的画布中( 从左到右,从上到下 写入这些字)。
ch_gen = character_generator(text)
    
for y in range(0, img_raw.size[1], int(font_size * font_space)):
    for x in range(0, img_raw.size[0], int(font_size * font_space)):
        draw.text((x, y), next(ch_gen), font=font, fill=img_array[x, y], direction=None)

  • 最后进行保存。
img_new.convert('RGB').save(join(outputs_folder, basename(path)))

完整代码如下:

from PIL import Image, ImageDraw, ImageFont
from glob import glob
from os.path import basename, join

# 字体大小
font_size = 7
# 字体间距,1 即间距正好为字体大小,紧凑排布,1.2 为字体大小的 1.2 倍
font_space = 1.2
# 绘制的文本
text = '情人节快乐'
# 字体文件的路径
font_file = 'C:/Windows/Fonts/Alibaba-PuHuiTi-Regular.ttf'

# 输入图片路径
inputs_folder = 'C:/Users/admin/Desktop/inputs'
# 输出图片路径
outputs_folder = 'C:/Users/admin/Desktop/outputs'

def process(path):
    img_raw = Image.open(path)
    img_array = img_raw.load()
    img_new = Image.new('RGB', img_raw.size, (0, 0, 0))
    draw = ImageDraw.Draw(img_new)
    font = ImageFont.truetype(font_file, size=font_size)

    def character_generator(text):
        while True:
            for i in range(len(text)):
                yield text[i]
    
    ch_gen = character_generator(text)
    
    for y in range(0, img_raw.size[1], int(font_size * font_space)):
        for x in range(0, img_raw.size[0], int(font_size * font_space)):
            draw.text((x, y), next(ch_gen), font=font, fill=img_array[x, y], direction=None)
    
    img_new.convert('RGB').save(join(outputs_folder, basename(path)))

if __name__ == '__main__':
    for path in glob(join(inputs_folder, '*')):
        print('starting processing', path)
        process(path)
        print('finished processing', path)

注意:

  • 在使用字体 阿里巴巴普惠体R 时,需要将该字体 安装到系统中,不然可能会报错(仅对于windows系统,因为笔者没试过其他系统是否会出错)。

  • 另外,阿里巴巴普惠体R 字体的下载地址为 Github or 字体下载网

4. 效果

PS:以下图片来源网络

随便从网上找了几张 Hebe(田馥甄)的图片,作为代码测试的对象。


结果如下所示,看起来还是不错的。

写在最后:

参考资料:

更多资料:

如果此文章涉及侵权,还请私信作者删除,谢谢。

相关文章

  • 随笔 | 一段有趣的代码

    写在前面: 好久没有更新了,本来想着在2月14号发这篇随笔的,但是仔细想想,还是过两天再发比较合适,毕竟2月14号...

  • 一段有趣的代码

  • SDWebImage源码之宏定义dispatch_main_as

    今天在阅读 SDWebImage 的源码,发现了这段有趣的代码。 SDWebImage这个库里的一段宏定义代码: ...

  • 有趣的代码

    最近在工作中,有的时候想看看公司封装的组件,于是就点击进入项目中用到的组件代码中去,本来是想学习下,结果,却发现了...

  • 快的打车这段代码是什么水平?

    对于每天敲代码的程序员来说,代码就像情人。如果看到一段很有趣的代码,简直是喜出望外。有网友分享了自己写的某段代码,...

  • PHP学习笔记-goto语句

    最近遇到了了这样一段有趣的代码: 这段代码会输出什么呢?是输出if的内容还是else的内容? 但是他却if和els...

  • 第一行代码

    Android 第一行代码随笔

  • 有趣的代码细节

    byteToHexString LRU(Least Recently Used)近期最少使用算法 首字母大写

  • 有趣的代码注释

  • 一路上,天地间

    异于平日生活轨迹的事情总是让人难忘。昨晚,翻看了李娟的《阿勒泰的角落》。书里面是一段段的小随笔,有的有趣、有时难忘...

网友评论

      本文标题:随笔 | 一段有趣的代码

      本文链接:https://www.haomeiwen.com/subject/qokyfhtx.html