惊爆!Python打造花式照片墙!

news2024/12/23 9:25:00

大家注意:因为微信最近又改了推送机制,经常有小伙伴说错过了之前被删的文章,比如前阵子冒着风险写的爬虫,再比如一些限时福利,错过了就是错过了。

所以建议大家加个星标,就能第一时间收到推送。👇

83902f5852b801f5e17fc265078ed451.jpeg


前段时间在看照片墙,感觉用照片拼成各种形状还是蛮有意思的,将所有故事浓缩在一张图上。

于是做了2个张含韵的照片墙视频。照片墙1:女神做照片墙背景,可以将自己的背影放上去

8c4d30163e531125b751eabec1b2c7ca.gif

照片墙2:照片翻页,欣赏女神的无敌美颜

e0105f90a1923eb04015fc4e131a7292.gif

最终照片墙的效果还可以,但是用手动方式制作还是有些费时费力的。最近,看到python制作文字照片墙的简便方法,我们选3张图片:

4d8c82741a44882cdf345a63f9b333c2.png

让玫瑰花组成照片墙,代码运行效果图如下:

dcca22f77cc693e4e17a2b7d373009cf.png

有点小惊艳呀,怎么这么好看,放到视频中做素材:

401615b40314aaf2b8c2fc670505bf75.gif

多选几张图片效果又如何呢,30张刘亦菲的靓照组成照片墙:

ec792f18c2947bf3a1f540d312a73c6b.png

整体色调不如3张照片的玫瑰花那么统一了,单张照片都好看,拼一起怎么乱糟糟呢?

虽然如此,

但是玫瑰花开,美女成群,还是蛮有氛围的。

经过我的简单尝试,可以粗谈一下制作照片墙的两种方式了。

用Excel制作照片墙模板

这种方式来做简单的字符还好,如果制作汉字有些费事。

首先需要填充颜色,在Excel中画出需要的文字,再填充0,1数字,最后再制作数字矩阵二维数组。出问题时,需要反复地修改模板。总之,这一部分很耗时。

602310e862ae7586e709d5a40c70aeab.png

有没有不需要手动制作汉字模板,自动生成照片墙的方法呢?答案是通过点阵字的方式来实现汉字照片墙。

点阵字照片墙制作

点阵字是汉字在计算机中的存储形式,效果就如像素图。HZK16字库是符合GB2312标准的1616点阵字库,每个汉字模型需要1616共256个像素点来显示。效果如下图所示:

b224d301bacfaac0e34039984b4d92ca.png

照片墙制作

1.生成点阵字照片墙模板——一个二维数组,需要调用字库文件,本次运用了HZK16的字库文件。

2.用照片替换模板中的的符号,形成照片墙。

第一部分代码:生成点阵字照片墙模板

import binascii
import os
from PIL import Image
import random
import numpy as np

KEYS = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01]

'''
获取多个汉字点阵字
'''
def get_multiple_word_img(textStr):
    # 初始化16*16的点阵位置,每个汉字需要16*16=256个点来表示,需要32个字节才能显示一个汉字
    # 之所以32字节:256个点每个点是0或1,那么总共就是2的256次方,一个字节是2的8次方
    rect_list = [] * 16
    for i in range(16):
        rect_list.append([] * 16)

    for text in textStr:
        #获取中文的gb2312编码,一个汉字是由2个字节编码组成
        gb2312 = text.encode('gb2312')
        #将二进制编码数据转化为十六进制数据
        hex_str = binascii.b2a_hex(gb2312)
        #将数据按unicode转化为字符串
        result = str(hex_str, encoding='utf-8')

        #前两位对应汉字的第一个字节:区码,每一区记录94个字符
        area = eval('0x' + result[:2]) - 0xA0
        #后两位对应汉字的第二个字节:位码,是汉字在其区的位置
        index = eval('0x' + result[2:]) - 0xA0
        #汉字在HZK16中的绝对偏移位置,最后乘32是因为字库中的每个汉字字模都需要32字节
        offset = (94 * (area-1) + (index-1)) * 32

        font_rect = None

        #读取HZK16汉字库文件
        with open(r"D:\360极速浏览器下载\字库\16x16\hzk16H", "rb") as f:
            #找到目标汉字的偏移位置
            f.seek(offset)
            #从该字模数据中读取32字节数据
            font_rect = f.read(32)

        #font_rect的长度是32,此处相当于for k in range(16)
        for k in range(len(font_rect) // 2):
            #每行数据
            row_list = rect_list[k]
            for j in range(2):
                for i in range(8):
                    asc = font_rect[k * 2 + j]
                    #此处&为Python中的按位与运算符
                    flag = asc & KEYS[i]
                    #数据规则获取字模中数据添加到16行每行中16个位置处每个位置
                    row_list.append(flag)

    #根据获取到的16*16点阵信息,打印到控制台
    for row in rect_list:
        for i in row:
            if i:
                print('o', end=' ')
            else:
                print('.', end=' ')
        print()

    print('{}'.format(rect_list))
    #返回值为点阵二维列表
    return rect_list

get_multiple_word_img('爱')
输出的数字矩阵二维数组如下:
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 32, 16, 8, 0, 0, 0], [0, 64, 32, 16, 8, 4, 2, 1, 128, 64, 32, 16, 8, 0, 0,0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

需要注意的是:1.其中的数字128、64、32、16、8、4、2需要替换成1

321793e4939d126f67a101f60c193faa.png

2.再把1替换成5(或其它不是0和1的数字)

471d1647bdae13a7fea5d0cc6594f945.png

3.然后把0替换成1,目的是去掉背景,只显示汉字 4.最后把第二步的5替换成0 这样一番操作后,输出的二维数组就可以给第二部分代码用了。

第二部分代码:用照片替换模板中的指定字符,形成照片墙

此部分代码就是循环第一部分代码输出的二维数组列表, 用变量HEART_FRAME等于它。

注意:要提前从网上下载HZK16文件(资源不好找,我上传了http://ssw.fit/free/font_library.zip) ,并在代码中修改文件对应的路径。

from PIL import Image
import os

'''
根据指定的frame_name 获取photo_wall_FRAME
# 定义绘制图形的框架,1表示不填充,0表示用头像填充
'''
def get_photo_wall_FRAME(frame_name):
    FRAME_DIC = {}
    #Heart frame 21*17,Heart形状共128个0
    HEART_FRAME=[[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1]]
    FRAME_DIC["HEART_FRAME"]=HEART_FRAME

    # FRAME_DIC["LOVE_FRAME"]=LOVE_FRAME

    return FRAME_DIC[frame_name]

'''
生成照片墙
'''
def generate_photo_wall(FRAME,img_path,photo_folder_name):

    #导入图片
    #需要拼接的照片文件夹完整路径
    photo_folder = r'{}\{}'.format(img_path,photo_folder_name)

    #将以.jpg的图片放置于新键的列表中,为后续生成照片墙使用,目的是过滤掉非图片格式的文件
    pic_list = [] #存放图片位置
    for i in os.listdir(photo_folder):
        print(i)
        if i.endswith('.jpg') or i.endswith('.png') or i.endswith('.webp'):
            pic_list.append(i)
    total_photo =len(pic_list)
    print("文件夹中共有{}张照片".format(total_photo))

    print('正在创建照片墙...')

    # 设置图片的尺寸,所有图片尺寸要保持统一
    img_h = img_w = 192
    # 计算行数,即子列表的个数
    rows = len(FRAME)
    # 计算列数,即子列表中元素的个数
    columns = len(FRAME[0])

    #画图
    #使用Image.new()方法创建一个画布,一个白色图片
    # 第一个参数RGB
    # 第二个参数需要传入一个元组,元组的第一个参数是画布的宽,第二个是高
    # 第三个参数传入的是画布的颜色
    figure = Image.new("RGB", (img_w*columns, img_h*rows),"white")

    #将图片放在画布对应的位置,即数组中元素为0的位置

    # 表示图片的下标
    count = 0
    # 遍历行
    for i in range(len(FRAME)):
        # 遍历每行中的所有元素
        for j in range(len(FRAME[i])):
            # 如果元素是1,就不管它
            if FRAME[i][j] == 1:
                continue
            # 如果元素是非1,即0就放图片上去
            else:
                # 做个异常处理,防止有些图片打开失败,导致程序中断
                try:
                    #当照片数量不够时,循环使用已用过的照片,added by yimi on 20220521
                    if count == total_photo:
                        count = 0

                    # 使用Image.open("图片路径")方法获取图片对象
                    image = Image.open(os.path.join(photo_folder, pic_list[count]))

                except:
                    continue
                # resize((新的宽,新的高))用来改变图片的尺寸,接收一个元组
                image = image.resize((img_w, img_h))
                # 将修改尺寸后的图片(image)粘贴(paste)到画布(figure)上
                # 第一个参数 是图片对象
                # 第二个参数是 图片在画布上的位置,相当于单元格的位置
                figure.paste(image, (img_w*j, img_h*i))
                # 使用完一张图片就要记录下来,并开始使用下一张图片
                count += 1

    # 当循环结束,即表示照片墙图片已经完成
    # 将画好的画布显示出来
    figure.show()

    # 需要告知程序图片保存的路径
    figure.save(r'{}\{}_photo_wall1.png'.format(img_path,photo_folder_name),format="png")

    print('照片墙创建成功!')


#程序入口
if __name__=='__main__':

    #图片存放的路径(当前项目是所有图片统一放在了程序所在的文件夹路径下方了,运用代码时可以改成自己照片存放的路径即可。)
    img_path =r'Photo\img'

    #存放很多张照片集合的文件夹名称,将路径和文件夹名称分开保存在变量中是为了后续生成照片墙照片要用文件夹的名称
    photo_folder_name = 'baby'

    #照片墙框架类型:"LOVE_FRAME","HEART_FRAME"
    frame_name = "HEART_FRAME"

    #获取指定的照片墙框架
    FRAME = get_photo_wall_FRAME(frame_name)

    #生成照片墙
    generate_photo_wall(FRAME,'C:/drf2/drf2/图片',photo_folder_name)

交流群

时隔2个月,摸鱼学习交流群再次限时开放了。

3862637a8e926454905824445483751c.png

Python技术交流群(技术交流、摸鱼、白嫖课程为主)又不定时开放了,感兴趣的朋友,可以在下方公号内回复:666,即可进入,一起 100 天计划!

老规矩,酱友们还记得么,右下角的 “在看” 点一下,如果感觉文章内容不错的话,记得分享朋友圈让更多的人知道!

54628e74e7c643e67ac408d9419ffa4e.gif

【神秘礼包获取方式】
扫描下方二维码添加私人微信,再送一套精华电子书!,回复:电子书

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/614460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NXP IMX8M + Ethercat+Codesys工业实时运动控制解决方案

面向边缘计算应用的全新i.MX 8M Plus异构应用处理器,搭载专用神经网络加速器、独立实时子系统、双摄像头ISP、高性能DSP和GPU。 恩智浦半导体宣布推出i.MX 8M Plus应用处理器,进一步丰富其业界领先的产品组合。这是恩智浦首个集成了专用神经处理引擎&…

G0第25章:Gin框架进阶项目实战

1 Gin框架源码解析 通过阅读gin框架的源码来探究gin框架路由与中间件的秘密。 1.1 Gin框架路由详解 gin框架使用的是定制版本的httprouter,其路由的原理是大量使用公共前缀的树结构,它基本上是一个紧凑的Trie tree 或者只是(Radix Tree&am…

Linux Tomcat服务 虚拟主机 多实例部署

Tomcat 服务 Tomcat 是 Java 语言开发的,Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器。Tomcat 属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 java开发的JSP 动态页面程序的首选。一般…

Linux教程——常见Linux发行版本有哪些?

新手往往会被 Linux 众多的发行版本搞得一头雾水,我们首先来解释一下这个问题。 从技术上来说,李纳斯•托瓦兹开发的 Linux 只是一个内核。内核指的是一个提供设备驱动、文件系统、进程管理、网络通信等功能的系统软件,内核并不是一套完整的…

DDD领域模型

一、分层介绍 controller层:处理页面或者api请求的输入输出,定义VO(REQ,RES),没有业务逻辑,只做请求处理和下层逻辑接application层:处理跨领域domain的复杂逻辑,定义DTOdomain层:领域核心逻辑…

深入理解Qt多线程编程:QThread、QTimer与QAudioOutput的内在联系__QObject的主线程的事件循环

深入理解Qt多线程编程:QThread、QTimer与QAudioOutput的内在联系__QObject的主线程的事件循环 1. Qt多线程编程的基础1.1 QObject和线程(QObject and Threads)1.2 QThread的使用和理解(Understanding and Using QThread&#xff0…

C#,码海拾贝(35)——求“实对称矩阵““特征值与特征向量“的“雅可比法“之C#源代码

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 矩阵类 /// 作者&#xff1a;周长发 /// 改进&#xff1a;深度混淆 /// https://blog.csdn.net/beijinghorn /// </summary> public partial class Matrix {…

编码器 | 基于 Transformers 的编码器-解码器模型

基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶。本文简要介绍了神经编码器-解码器模型的历史&#xff0c;更多背景知识&#xff0c;建议读者阅读由 Sebastion Ruder 撰写的这篇精彩 博文。此外&#xff0c;建议读者对 自注意力 (…

【AUTOSAR】Bootloader说明(一)---- 时序流程

电机控制器选用TI TMS28xx DSP&#xff0c;包括boot-loader与应用软件两个部分。其中boot-loader包括下列内容&#xff1a; RAM自检应用程序有效性检查UDS命令处理FLASH操作 下面分别说明DSP上电后整个软件运行流程及程序刷新过程。 DSP软件执行流程 DSP复位后&#xff0c;将…

【Mysql基础】-关于常用的函数简单案例

目录 一、系统函数 二、日期函数 三、字符串函数数 说明&#xff1a;以下所有的操作在8.0的mysql数据库操作系统上操作 一、系统函数 1 显示连接列表&#xff1a;show PROCESSLIST; 2 MD5加密&#xff1a;select MD5("root") 二、日期函数 1、 推算一周之后的…

QMI8658 - 姿态传感的零偏(常值零偏)标定

1. 零偏 理论上在静止状态下三轴输出为0,0,0&#xff0c;但实际上输出有一个小的偏置&#xff0c;这是零偏的静态分量&#xff08;也称固定零偏&#xff09;。 陀螺生产出来后就一直固定不变的零偏值。对于传统的高性能惯性器件来说&#xff0c;该误差在出厂标定时往往就被补偿…

《水经注地图服务》用户如何登录?

《水经注地图服务》&#xff08;WeServer&#xff09;是一款可快速发布全国乃至全球海量卫星影像的地图发布服务产品&#xff0c;该产品完全遵循OGC相关协议标准&#xff0c;是一个基于若干项目成功经验总结的产品。它可以轻松发布100TB级海量卫星影像&#xff0c;从而使“在内…

如何使用 Raycast 一键打开预设工作环境

工作中&#xff0c;你一定遇到过这样的场景&#xff1a;你正在认真写代码&#xff0c;线上突然出现报警。看到报警信息之后&#xff0c;你不得不打开浏览器&#xff0c;点开收藏夹&#xff0c;打开监控页面、告警页面、trace 页面、日志搜索平台……有时&#xff0c;还需要打开…

chatgpt赋能python:Python取值:了解基础知识和应用方法

Python取值&#xff1a;了解基础知识和应用方法 什么是Python取值&#xff1f; Python取值是指从一个对象中获取信息或者值。对象可以包括列表、字典、元组、变量等。Python提供了多种方法来取值&#xff0c;包括基础的索引和切片操作&#xff0c;以及高级的列表推导式、字典…

MySQL JDBC详解

文章目录 简介JDBC APIJDBC Driver ManagerJDBC 驱动 JDBC 开发步骤一&#xff0c;导入 JDBC 驱动包&#xff0c;并加载驱动类二&#xff0c;建立数据库连接三&#xff0c;发送 SQL 语句&#xff0c;并获取执行结果Statement 对象PreparedStatement 对象 四&#xff0c;处理返回…

ADAS方案的简单比较

ADAS方案的简单比较 1 概述2 厂商Tesla硬件布局网络基础结构&#xff1a;HydraNet多头网络 NVIDIA百度&#xff08;Apollo&#xff09;版本历史硬件布局软件框架各版本框架 WaymoVolvo-Uber 3 芯片4 其他from [最全自动驾驶技术架构和综述](https://blog.csdn.net/buptgshengod…

项目质量管理

质量与项目质量 质量的定义&#xff1a;一组固有特征满足要求的程序。 质量是反应实体主题明确和隐含需求的能力的特性总和 质量与等级的关系&#xff1a; 一个低等级&#xff08;功能有限&#xff09;&#xff0c;高质量&#xff08;无明显缺陷&#xff0c;用户手册易读&am…

《Datawhale南瓜书》出第二版啦!

Datawhale干货 作者&#xff1a;Datawhale开源项目团队 作为机器学习的入门经典教材&#xff0c;周志华老师的《机器学习》&#xff0c;自2016年1月底出版以来&#xff0c;首印5000册一周售罄&#xff0c;并在8个月内重印9次。先后登上了亚马逊&#xff0c;京东&#xff0c;当…

【运维知识进阶篇】iptables防火墙详解

这篇文章给大家介绍下iptables防火墙&#xff0c;防火墙大致分三种&#xff0c;分别是硬件、软件和云防火墙。硬件的话部署在企业网络的入口&#xff0c;有三层路由的H3C、华为、Cisco&#xff08;思科&#xff09;&#xff0c;还有深信服等等&#xff1b;软件的话一般是开源软…

【服务器】iPad远程服务器进行开发

文章目录 前言1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. iPad通过软件远程vscode6.1 创建TCP隧道 7. ipad远…