利用Python在Excel中绘制图片的实现方法
本文介绍如何使用Python在Excel中绘制图片。通过OpenCV读取图像像素RGB值,利用Pandas处理数据,结合xlsxwriter调整行列尺寸,最后使用openpyxl将颜色填充至单元格。该方法适用于低分辨率图像,高像素图片可能导致Excel卡顿。
实现原理与核心步骤
在Excel中“画图”的本质是将图像的像素颜色映射到Excel单元格的背景色上。具体流程分为以下几个阶段:
- 图像读取:使用OpenCV读取图片,获取每个像素点的RGB值。
- 数据转换:将RGB十进制值转换为十六进制颜色代码。
- Excel初始化:使用xlsxwriter创建Excel文件,并调整单元格尺寸以匹配像素比例。
- 颜色填充:使用openpyxl遍历单元格,将对应的十六进制颜色应用到单元格背景。
环境准备
首先需要安装必要的Python库。由于OpenCV的安装可能较慢,建议使用国内镜像源。
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python在代码中,我们需要导入以下库:
cv2:用于读取图像和处理像素数据。xlsxwriter:用于创建Excel文件并调整行列宽度和高度。openpyxl:用于加载Excel文件并填充单元格颜色。numpy和pandas:用于高效处理数组和DataFrame数据。
import cv2 #导入OpenCV库
import xlsxwriter #利用这个调整行高列宽
import openpyxl #利用这个填充颜色
import numpy as np #下面这两个是数据存储的两种方式,用此种方式处理数据,比列表高效,具体可自行查看文档
import pandas as pd核心代码实现
我们将整个过程封装在一个类ImageToExcel中,包含初始化、尺寸调整、数据转换和颜色填充四个主要方法。
1. 初始化与图像读取
在初始化方法中,使用cv2.imread读取图片,并保存Excel文件路径。
class ImageToExcel():
def __init__(self,image_path,excel_path):
self.imgviewx=cv2.imread(image_path,cv2.IMREAD_COLOR)
self.excel_path=excel_path2. 调整Excel行列尺寸
为了使Excel单元格看起来接近正方形,需要调整列宽和行高。使用xlsxwriter创建文件并添加工作表。
#excel行高列宽调整
def excel_size(self):
workbook = xlsxwriter.Workbook(self.excel_path)
worksheet = workbook.add_worksheet('test')
worksheet.set_column('A:CAA', 1)
for x in range(2000):worksheet.set_row(x, 8.4)
workbook.close()注意:列宽设置为1时,实际显示约为0.94。行高需要通过循环单独设置,这里设置为8.4。
3. 十进制转十六进制
将RGB的十进制值转换为十六进制颜色代码。使用hex函数,并去除前缀0x,不足两位时补0。
#10进制转化为16进制
def ten2_16(self,num):
num1 = hex(num).replace('0x', '')
return num1 if len(num1) > 1 else '0' + num14. 获取RGB数据并转换
使用numpy和pandas处理图像数据。注意OpenCV读取的RGB顺序是BGR,因此需要调整通道顺序。
#获取像素数据并转化为16进制
def get_rgb_data(self):
self.excel_size()
data_r=pd.DataFrame( np.array(self.imgviewx)[:,:,2] ).applymap(self.ten2_16)
data_g=pd.DataFrame( np.array(self.imgviewx)[:,:,1] ).applymap(self.ten2_16)
data_b=pd.DataFrame( np.array(self.imgviewx)[:,:,0] ).applymap(self.ten2_16)
return (data_r+data_g+data_b).values这里分别提取R、G、B通道,转换为十六进制后拼接成颜色代码。
5. 颜色填充
使用openpyxl加载Excel文件,遍历每个单元格并填充颜色。
def color_fill(self):
rgb_list=self.get_rgb_data()
wb = openpyxl.load_workbook(self.excel_path)
ws = wb['test']
for x,tmp1 in list(enumerate(rgb_list)):
print('总共有%s行,已填充%s行,还剩下%s行'%(len(rgb_list),x+1,len(rgb_list)-x-1))
for y ,tmp2 in list(enumerate(tmp1)):
ws.cell(x+1,y+1).fill = openpyxl.styles.fills.GradientFill(stop=[str(tmp2),str(tmp2)])
wb.save(self.excel_path)完整代码与运行示例
以下是完整的代码实现,包括初始化、尺寸调整、数据转换和颜色填充。
import cv2 #导入OpenCV库
import xlsxwriter #利用这个调整行高列宽
import openpyxl #利用这个填充颜色
import numpy as np #下面这两个是数据存储的两种方式,用此种方式处理数据,比列表高效
import pandas as pd
class ImageToExcel():
#初始化
def __init__(self,image_path,excel_path):
self.imgviewx=cv2.imread(image_path,cv2.IMREAD_COLOR)
self.excel_path=excel_path
# excel行高列宽调整
def excel_size(self):
workbook = xlsxwriter.Workbook(self.excel_path)
worksheet = workbook.add_worksheet('test')
worksheet.set_column('A:CAA', 1)
for x in range(2000): worksheet.set_row(x, 8.4)
workbook.close()
#rgb转16进制颜色码
def ten2_16(self,num):
tmp = hex(num).replace('0x', '')
return tmp if len(tmp) > 1 else '0' + tmp
#获取像素数据并转化为16进制
def get_rgb_data(self):
self.excel_size()
data_r=pd.DataFrame( np.array(self.imgviewx)[:,:,2] ).applymap(self.ten2_16)
data_g=pd.DataFrame( np.array(self.imgviewx)[:,:,1] ).applymap(self.ten2_16)
data_b=pd.DataFrame( np.array(self.imgviewx)[:,:,0] ).applymap(self.ten2_16)
return (data_r+data_g+data_b).values
#颜色填充
def color_fill(self):
rgb_list=self.get_rgb_data()
wb = openpyxl.load_workbook(self.excel_path)
ws = wb['test']
for x,tmp1 in list(enumerate(rgb_list)):
print('总共有%s行,已填充%s行,还剩下%s行'%(len(rgb_list),x+1,len(rgb_list)-x-1))
for y ,tmp2 in list(enumerate(tmp1)):
ws.cell(x+1,y+1).fill = openpyxl.styles.fills.GradientFill(stop=[str(tmp2),str(tmp2)])
wb.save(self.excel_path)
excel_path='test23.xlsx'
image_path='tttt.png'
image=ImageToExcel(image_path,excel_path)
image.color_fill()注意事项
- 性能问题:高像素图片可能导致Excel卡顿。测试分辨率342*218时已影响流畅度,可通过增大步长降低像素密度。
- 颜色顺序:OpenCV读取的RGB顺序是BGR,提取时需调整通道顺序。
- 备份数据:操作前请备份Excel文件,避免数据丢失。





以上就是利用Python在Excel中绘制图片的详细内容,更多关于Python Excel画图、OpenCV与Openpyxl结合使用的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









