娱乐时间 —— 用python将图片转为excel十字绘

news/2024/7/21 5:05:53 标签: python, excel, 十字, 图片, 绘画
       最近看蛮多朋友在玩,要么只能画比较简单的,要么非常花时间。想了下本质上就是把excel对应的单元格涂色,如果能知道哪些格子要上什么颜色,用编程来实现图片转为excel十字绘应该是很方便的。
       图片的每一个像素点都可以数值化,那么将构成图片的每一个像素点填充到excel的单元格中去,然后合理调整单元格长宽比便可以拼成一副画。反过来想,用一张单元格足够小的excel表格将图片蒙上一层,犹如用 一张网去切割这张图片图片被切割成一小块一小块 ,如果网格足够细,每一小块里面的颜色几乎只有一种,这样就可以用一个三元组(RGB)来刻画 ,这样一张图片就可以由一个很大的矩阵来刻画 ,矩阵中的每一个元素都是一个 RGB三元组。不管从图片excel还是从excel图片,我们都可以构建一个一一映射关系,我们便可以依循这个理论在excel作画。
       网上搜索了下用python就可以实现,主要是以下两个模块:
  • Pillow(PIL,Python Imaging Library):强大的图形处理库
  • openpyxl:用于操作excel的模板,之前也用到过

代码主要来自:程序员如何 10 分钟用 Python 画出蒙娜丽莎? - 知乎

直接运行会有报错,需要稍微修改:

  • 获取列信息:新版本修改了属性名,用原文的会报错
python"># 修正前
column = col[0].column
# 修正後
column = col[0].column_letter
  • 调整列宽部分:原文的1会让图片变得奇扁无比,测试设为8大小会比较合适
python"> worksheet.column_dimensions[_w].width = 8
  • 调整单元格大小:相对来说400更清晰
python">MAX_WIDTH = 400
MAX_HEIGHT = 400

修改后代码如下:

python">#!/usr/bin/env python
# -*- coding:utf-8 -*-
#@Time  : 2023/09/10
#@Author: Hehuyi_In
#@File  : picture_to_excel.py

from PIL import Image
import openpyxl
from openpyxl.styles import fills
import os

MAX_WIDTH = 400
MAX_HEIGHT = 400

# excel的单元格默认是长方形,修改为正方形才不会使图片变形
# 调整excel每个单元格大小,避免图片过大,excel无法打开
# 过小电子画会过于模糊,太大excel可能无法打开
def resize(img):
    w, h = img.size
    if w > MAX_WIDTH:
        h = MAX_WIDTH / w * h
        w = MAX_WIDTH

    if h > MAX_HEIGHT:
        w = MAX_HEIGHT / h * w
        h = MAX_HEIGHT
    return img.resize((int(w), int(h)), Image.ANTIALIAS)

# 整型转16进制
# getpixel()获取的颜色值是rgb十进制的,但fills.PatternFill 里的fgColor`参数接收到的颜色值是十六进制的值,因此需要转换
def int_to_16(num):
    num1 = hex(num).replace('0x', '')
    # 位数只有一位时在前面补零
    num2 = num1 if len(num1) > 1 else '0' + num1
    return num2

# 绘图函数
def draw_jpg(img_path):
    # 打开图片
    img_pic = resize(Image.open(img_path))
    img_name = os.path.basename(img_path)

    # 输出的excel名,若已存在则删除
    out_file = img_name.split('.')[0] + '.xlsx'
    if os.path.exists(out_file):
        os.remove(out_file)

    # 新建一个excel文件
    workbook = openpyxl.Workbook()
    # 激活一个工作表(sheet)
    worksheet = workbook.active

    width, height = img_pic.size

    # 循环处理图片中的每个像素
    for w in range(1, width + 1):
        for h in range(1, height + 1):
            # getpixel函数用于获取像素色彩值,入参为像素坐标
            if img_pic.mode == 'RGB':
                r, g, b = img_pic.getpixel((w - 1, h - 1))
            elif img_pic.mode == 'RGBA':
                r, g, b, a = img_pic.getpixel((w - 1, h - 1))

            # 将rgb值转换为16进制
            hex_rgb = int_to_16(r) + int_to_16(g) + int_to_16(b)

            # 定位每个单元格
            cell = worksheet.cell(column=w, row=h)

            # 第一行
            if h == 1:
                _w = cell.column_letter
                _h = cell.col_idx
                # 调整列宽
                worksheet.column_dimensions[_w].width = 8
            # 调整行高
            worksheet.row_dimensions[h].height = 45
            # 填充颜色,fill_type是填充类型,fgColor是填充的颜色
            cell.fill = fills.PatternFill(fill_type="solid", fgColor=hex_rgb)

    print('saving...')
    workbook.save(out_file)
    print('success!')


if __name__ == '__main__':
    draw_jpg('lyx.jpg')

效果图,以我这个头像为例(excel画出来的图太大了,这里截了一部分)

这要是手工画一张不得画几个月...但通过程序可以直接秒出,牛哇~

python">参考
https://zhuanlan.zhihu.com/p/95720761
https://blog.51cto.com/u_15255081/6164226
https://blog.csdn.net/weixin_43790276/article/details/108478270
https://qiita.com/gorimacho/items/63707223e692f7401988


http://www.niftyadmin.cn/n/5016281.html

相关文章

Nginx 部署离线瓦片服务

nginx 部署离线瓦片服务,地图资源加载 一、下载离线瓦片数据,部署在本地二、nginx.conf 配置文件三、浏览器中访问 上一篇: nginx 安装与部署 一、下载离线瓦片数据,部署在本地 二、nginx.conf 配置文件 #user nobody; worker_…

diskqueue第五篇 - 追尾检测,错误处理,如何正常关闭

diskqueue是nsq消息持久化的核心,内容较多,故分为多篇 1. diskqueue第一篇 - 是什么,为什么需要它,整体架构图,对外接口 2. diskqueue第二篇 - 元数据文件,数据文件,启动入口,元数…

python经典100题之判断今年的第几天

可以通过datetime模块来计算。具体实现如下: import datetimeyear int(input("请输入年份:")) month int(input("请输入月份:")) day int(input("请输入日期:"))date datetime.date(year, mon…

vue3的生命周期

1.vue3生命周期官方流程图 2.vue3中的选项式生命周期 vue3中的选项式生命周期钩子基本与vue2中的大体相同,它们都是定义在 vue实例的对象参数中的函数,它们在vue中实例的生命周期的不同阶段被调用。生命周期函数钩子会在我们的实例挂载,更新…

MySQL——常见问题

NULL和空值的区别 1、空值不占空间,NULL值占空间。当字段不为NULL时,也可以插入空值。 2、当使用 IS NOT NULL 或者 IS NULL 时,只能查出字段中没有不为NULL的或者为 NULL 的,不能查出空值。 3、判断NULL 用IS NULL 或者 is no…

python创建exe文件

1、搭建环境 pip install pyinstaller 2、准备测试代码 exe_test.py import timeprint("hello") print("hello") print("hello") print("hello")time.sleep(5) 注:添加sleep以便在执行exe文件的时候能看到结果 3、生…

c++day3---9.8

1> 自行封装一个栈的类,包含私有成员属性:栈的数组、记录栈顶的变量 成员函数完成:构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 头文件: #ifndef Z_H #define Z_H #inclu…

Java中同时POST文件和提交JSON数据的方法

一、引言 在Java中,可以使用java.net.URLConnection类来进行HTTP请求,并实现同时POST文件和提交JSON数据的功能。下面将通过一篇文章的形式为您详细讲解这个过程。 二、实现步骤 步骤一:导入所需的类库 首先,你需要导入以下类…