利用python在excel中画图的实现方法


Posted in Python onMarch 17, 2020

一、前言

以前大学时候,学EXCEL看到N多大神利用excel画图,觉得很不可思议。今个学了一个来月python,膨胀了就想用excel画图。当然,其实用画图这个词不甚严谨,实际上是利用opencv遍历每一个像素的rgb值,再将其转化为16进制,最后调用openpyxl进行填充即可。

1.1、实现效果

效果如下图

利用python在excel中画图的实现方法

1.2、需要用到的库的安装

需要用到库如下:

import cv2   #导入OpenCV库
import xlsxwriter #利用这个调整行高列宽
import openpyxl  #利用这个填充颜色
import numpy as np #下面这两个是数据存储的两种方式,用此种方式处理数据,比列表高效,具体可自行查看文档
import pandas as pd

除了第一个库其他的可以直接用pip在命令提示行进行安装,或者利用编辑器的一些自动安装功能也非常的方便,具体的请参看这篇文章 的第三节: 三、开始安装

第一个库如果你直接用pip3 install opencv-python 进行安装的话,无论你网速多么快,都会非常慢几k/s,如下:

利用python在excel中画图的实现方法

如果能安装好还行,关键有的可能等上几分钟也不行,直接出现几十行的红色字看的头疼。几经百度后才知道是安装源的问题,切换为国内的安装源即可,利用如下命令,

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

如下图,我准备截取安装速度和上面的作对比的,结果直接安装好了

利用python在excel中画图的实现方法

二、代码分开讲解

本文我们利用面相对象的编程思维进行。

2.1、对象的定义以及初始化

class ImageToExcel():
 def __init__(self,image_path,excel_path):
  self.imgviewx=cv2.imread(image_path,cv2.IMREAD_COLOR)
  self.excel_path=excel_path

前面两行很好理解就是定义对象的格式以及初始化对象

其中image_path和excel_path这两个变量是你的图像储存路径和后续的excel文件保存位置。

第三行self.imgviewx=cv2.imread(image_path,cv2.IMREAD_COLOR)意思是调用opencv的imread读取图片。其中第一个参数就是对象实例化时候传递进来的图像储存路径。该函数返回的是一个三维数组,分别表示x,y,rgb 就是x,y坐标对应的rgb值,其中x,y单位为1像素。最后将这个三维数组传递给对象的一个属性imgviewx,等待后续对象方法调用。我们将之打印出来如下。

利用python在excel中画图的实现方法

第四行<<self.excel_path=excel_path>>是将对象实例化时候传递进来的excel_path传递给对象的属性excel_path,同样等待后续对象的方法调用。

2.2、对象的方法

1:行高列宽调整,以防止图像变形

#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()

这个其实你可以后续在excel中调整也可以。
第二行第三行基本一看就懂,就是在你刚开始对象实例化时候传入的一个路径中创建一个工作簿并添加一个名为test的工作表。
第三行意思是将A列到CAA列的列宽设置为1(注意:这里面设置为1不知道为什么在工作表中就是0.94,列宽同样小点
第四行意思同样,不过行高不能批量只能通过循环。
最后一样看着像关闭,其实最主要功能是保存,没有这一行,前面的所有设置都不会被保存。

2.3、对象的方法2:10进制转化为16进制

#10进制转化为16进制
 def ten2_16(self,num):
  num1 = hex(num).replace('0x', '')
  return num1 if len(num1) > 1 else '0' + num1

这个方法不用细说,就是利用系统自带的函数hex将10进制转化为16进制。我们都知道hex返回的16进制是以0x开头的,而16进制颜色码中明显没有,所以要用replace去掉。
如果rgb值是16以内的,以16进制显示的话会是1位数,而同样这个在16进制颜色码中也没有,所以最后一行的意思就是一位数的话在开头补0。

2.4、对象的方法3:获取r、g、b值并运用方法1转化为16进制颜色码

#获取像素数据并转化为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

其中第二行<<self.excel_size() >>是在本方法本调用时候先调用方法1调整行高列宽。我们后面说,这关系到对象方法之间的参数传递,我们后续说。
三四五行的代码结构一样,我们挑一个说。比如第三行data_r=pd.DataFrame( np.array(self.imgviewx)[:,:,2] ).applymap(self.ten2_16)这个代码我们可以拆开成下面的代码

r=np.array(self.imgviewx)[:,:,2]
tmp=pd.DataFrame( r )
data_r=tmp.applymap(self.ten2_16)

这下就容易懂了
第一行意思是将刚开始对象初始化时候得到的包含目标图片的所有像素点的rgb值的三维列表转化为数组并提取其中的r。
第二行是将第一行得到的数组转化为DataFrame对象并存储在tmp变量中,以便第三行的处理。
第三行是利用DataFrame中的applymap将r值转化为16进制。

最后一行<<return (data_r+data_g+data_b).values>>意思是将转化为16进制的rgb值合并后就得到了16进制的颜色码并转化为数组。

2.5、对象的方法4;颜色填充

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)

第二行<<rgb_list=self.get_rgb_data()>>是不是似曾相识,对,就是在方法2中调用方法1时候用的。
这里就是在本方法也就是方法3中调用方法2。唯一的区别就是有没有返回值。
我们这样在方法3中调用方法2然后方法2中调用方法1。这样在对象外的时候我们就只用对象实例化并调用方法3即可实现功能。
第三行、第四行就是调用openpyxl.load_workbook打开我们在方法1中新建的工作簿中的test工作表
五到七行两个循环嵌套很容易懂就是利用循环遍历每个工作表
第八行的代码可能可以简化 ,这个是我修改网上的一个填充渐变色的代码。
最后一行就是工作表的保存,没什么可说的。

三、完整代码

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()

最后四行前两行可以直接写在第三行中,就是对象的实例化中
另外还有一点,image_path中的 tttt.jpg是直接和我的py文件放在一起的,不然运行会报错。

四、结语

好啦,到此所有东西已全部搞定,当然还有很多要注意的,
第一、方法3中红绿蓝的提取中这部分的编号是刚好相反的,提取时候需要注意
如下

利用python在excel中画图的实现方法

当然你也可以尝试改变这个值看最后会得到什么结果。蓝色的太阳 红色的天空 或者是绿色的帽子,哈哈 好吧这个就你们自己发挥了。
第二、除了以上一点需要注意的,还有一个需要注意,就是像素不能太高。我测试了下342*218的话我的i7-6700u打开excel就不是很流畅了。
你可以遍历的时候以2个像素点或者四个像素点为步长,不过这样我没试过,可能颗粒感比较明显吧(自己猜测没试过),或者把原始图片修改下。

到此这篇关于利用python在excel中画图的实现方法的文章就介绍到这了,更多相关python excel画图内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python画图学习入门教程
Jul 01 Python
Django实现快速分页的方法实例
Oct 22 Python
python回调函数中使用多线程的方法
Dec 25 Python
Python中join函数简单代码示例
Jan 09 Python
python 实现数字字符串左侧补零的方法
Dec 04 Python
对python内置map和six.moves.map的区别详解
Dec 19 Python
python使用socket 先读取长度,在读取报文内容示例
Sep 26 Python
Python Pandas 转换unix时间戳方式
Dec 07 Python
python使用html2text库实现从HTML转markdown的方法详解
Feb 21 Python
Django框架静态文件处理、中间件、上传文件操作实例详解
Feb 29 Python
实战Python爬虫爬取酷我音乐
Apr 11 Python
Python中np.random.randint()参数详解及用法实例
Sep 23 Python
Python reversed函数及使用方法解析
Mar 17 #Python
使用python自动追踪你的快递(物流推送邮箱)
Mar 17 #Python
windows、linux下打包Python3程序详细方法
Mar 17 #Python
Python任务自动化工具tox使用教程
Mar 17 #Python
vue常用指令代码实例总结
Mar 16 #Python
django-利用session机制实现唯一登录的例子
Mar 16 #Python
python安装dlib库报错问题及解决方法
Mar 16 #Python
You might like
用PHP和ACCESS写聊天室(二)
2006/10/09 PHP
php,ajax实现分页
2008/03/27 PHP
PHP面向对象学习笔记之一 基础概念
2012/10/06 PHP
PHP三元运算的2种写法代码实例
2014/05/12 PHP
php中ob_get_length缓冲与获取缓冲长度实例
2014/11/20 PHP
php实现的树形结构数据存取类实例
2014/11/29 PHP
修复ShopNC使用QQ 互联时提示100010 错误
2015/11/08 PHP
tp5.1 框架数据库常见操作详解【添加、删除、更新、查询】
2020/05/26 PHP
Prototype使用指南之array.js
2007/01/10 Javascript
网站404页面3秒后跳到首页的实例代码
2013/08/16 Javascript
对new functionName()定义一个函数的理解
2014/05/22 Javascript
通过XMLHttpRequest和jQuery实现ajax的几种方式
2015/08/28 Javascript
jquery实现可点击伸缩与展开的菜单效果代码
2015/08/31 Javascript
Node.js与Sails redis组件的使用教程
2017/02/14 Javascript
Vue2递归组件实现树形菜单
2017/04/10 Javascript
three.js利用卷积法如何实现物体描边效果
2019/11/27 Javascript
详解webpack-dev-middleware 源码解读
2020/03/23 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
JavaScript 实现拖拽效果组件功能(兼容移动端)
2020/11/11 Javascript
python 图片验证码代码
2008/12/07 Python
Python六大开源框架对比
2015/10/19 Python
对Python实现累加函数的方法详解
2019/01/23 Python
scrapy-redis的安装部署步骤讲解
2019/02/27 Python
python按顺序重命名文件并分类转移到各个文件夹中的实现代码
2020/07/21 Python
Python2及Python3如何实现兼容切换
2020/09/01 Python
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
canvas之万花筒效果的简单实现(推荐)
2016/08/16 HTML / CSS
巴塞罗那观光通票:Barcelona Pass
2019/10/30 全球购物
机械设计专业应届生求职信
2013/11/21 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
倡议书格式模板
2014/05/13 职场文书
个人事迹材料怎么写
2014/12/30 职场文书
高三英语复习计划
2015/01/19 职场文书
自愿离婚协议书2015
2015/01/26 职场文书
检讨书范文300字
2015/01/28 职场文书
golang 实用库gotable的具体使用
2021/07/01 Golang