ISEE小语
“我们常常看到的风景是:一个人总在仰望和羡慕着别人的幸福,一回头,却发现,自己正被别人仰望和羡慕着。”
——马德
首先,这里非常感谢@可乐拉环同学的反馈^^
在06月09日的分享的【惊艳了,Python可以分析一张图片中包含有几种颜色?(附源码)】
惊艳了,Python可以分析一张图片中包含有几种颜色?(附源码)
ISEE小栈,公众号:ISEE小栈惊艳了,Python可以分析一张图片中包含有几种颜色?(附源码)
文章中,无法使用Microsoft Office Excel打开其中的Excel文件。
看到这个问题,小栈先说一下抱歉~~
第一是 一直没有发现
第二是 当初实例是使用WPS打开的,在分享中没说明。
没想到Microsoft Office Excel上会有问题!
从提示信息上看,这个问题应该是格式/样式不兼容的引起的!
小栈找到原文,事情并没有想象那么简单,发现不单单是Excel打不开的问题,即使是原来使用WPS打开的Excel文件,里面“颜色” 列数据也是不全的。
于是,小栈分别对WPS和Microsoft Office Excel测试验证
发现在WPS中,所有数据都在一个Excel文档中,“颜色” 列只显示在64000行
而在Microsoft Office Excel中“颜色” 列显示在65430行,只要超过就会报以上出现的问题。
总结下来就是两个表格软件,打开同一个Excel文件,两种显示结果:
软件 | “颜色”列显示行数 |
WPS Office | 64000 |
Microsoft Office Excel | 65430 |
*个人验证结果,非官方数据
为什么会这样???我也想知道⊙﹏⊙
那么,现在要解决的问题是 既能让 “颜色” 列都显示,又可以在Microsoft Office Excel软件正常打开。
目前没有特别完美的办法将所有颜色分析数据放在一个Excel文档中,小栈目前解决的方式是 按照显示的行数,切分多个文档保存数据。
环境:
Pycharm
Python 3.9.16
安装:
本次我们用到了两个三方包协助,一个是“openpyxl”,另一个是“pillow”。
用以下方式可自行安装:
pip install pillow==10.3.0
pip install openpyxl==3.1.3
先看实际效果
准备一张图片
首先,准备一张所要分析的图片,以下是实例中所用到的:
实现原理
主要实现步骤:
读取图片:确保图片是在RGB模式下计数每种颜色的像素数。
转换颜色编码:将RGB颜色转换为颜色编号。
保存Excel:将颜色编码及呈现的颜色,一一对应保存到Excel中。这里我们为了兼容WPS显示的行数,我们按每64000行保存至一文档中进行切分。
读取图片
首先,将准备的图片命名为image.png,放在当前文件夹下
然后,加载图片、读取所有像素、去重相同颜色,这个时候会打印出图片中所有的颜色和它们各自的计数,包括非常微小的变化,因为它是基于像素级的颜色读取。
from PIL import Image
from collections import Counter
# 加载图片
image_msg = Image.open('image.png')
# 将图片转换为RGB模式
image_msg = image_msg.convert('RGB')
# 获取图片中的所有像素
all_pixels = list(image_msg.getdata())
# 计算每种颜色的出现次数
color_counts = Counter(all_pixels)
# 去重后的颜色列表转换为集合
RGB_colors_ = set(color_counts.keys())
# 打印去重后的颜色
print(f'所有的颜色值: {RGB_colors_}')
(左右滑动查看完整代码)
结果:
其实很多数字,其实也看不明白,不用担心,这个只是颜色值。
接下来就是需要将这些颜色值转换为颜色编号。
转换颜值编码
我们将以上的颜色值转换为颜色编码
在示例中为了更清晰地看出是什么颜色,我们将少部分颜色值进行转换。
换个说法就是将转换RGB到十六进制颜色代码。
# -*- coding: utf-8 -*-
# 截取6个RGB颜色值集合
RGB_colors = {(159, 46, 163), (136, 138, 228), (102, 26, 38), (194, 88, 201), (216, 48, 44), (50, 4, 88)}
hex_colors = []
for rgb_color in RGB_colors:
hex_color = '#{0:02x}{1:02x}{2:02x}'.format(*rgb_color)
hex_colors.append(hex_color)
# 打印十六进制颜色代码
print("打印十六进制颜色代码:", hex_colors)
(左右滑动查看完整代码)
打印十六进制颜色代码结果:
接下来我们用取色工具校验两个颜色,看一下效果:
颜色值:(159, 46, 163)
颜色代码:'#9f2ea3'
颜色值:(136, 138, 228)
颜色代码:'#888ae4'
OK,剩下的就不一一贴出来了,有兴趣的可自行试。
保存Excel
我们以上输出的颜色值和颜色代码为例,将结果输出保存到Excel中:
from openpyxl import Workbook
from openpyxl.styles import PatternFill
RGB_colors = [{'(159, 46, 163)': '#9f2ea3'}, {'(136, 138, 228)': '#888ae4'}, {'(102, 26, 38)': '#661a26'},
{'(194, 88, 201)': '#c258c9'}, {'(216, 48, 44)': '#d8302c'}, {'(50, 4, 88)': '#320458'}]
wb = Workbook()
ws = wb.active
ws.cell(row=1, column=1).value = "颜色值"
ws.cell(row=1, column=2).value = "颜色编号"
ws.cell(row=1, column=3).value = "颜色"
for index, rgb_color in enumerate(RGB_colors, start=2):
for key, value in rgb_color.items():
hex_color = 'FF' + value.replace('#', '')
ws.cell(row=index, column=1).value = key
fill = PatternFill(start_color=hex_color, end_color=hex_color, fill_type="solid")
ws.cell(row=index, column=2).value = hex_color
ws.cell(row=index, column=3).fill = fill
wb.save('图片颜色分析统计.xlsx')
(左右滑动查看完整代码)
注:其中有一个特殊的处理,就是在保存到Excel中时,openpyxl三方库颜色需要以 "FF" 开头的十六进制格式。其中在RGB颜色代码前面加上了 'FF',这表示颜色是完全不透明的。
Excel中效果:
完整实例
按照WPS显示 64000 行进行切分,将结果输出保存到Excel中:
# -*- coding: utf-8 -*-
from PIL import Image
from collections import Counter
from openpyxl.styles import PatternFill
from openpyxl.workbook import Workbook
# 加载图片
image_msg = Image.open('image.png')
# 将图片转换为RGB模式
image_msg = image_msg.convert('RGB')
# 获取图片中的所有像素
all_pixels = list(image_msg.getdata())
# 计算每种颜色的出现次数
color_counts = Counter(all_pixels)
# 去重后的颜色列表
RGB_colors_ = list(set(color_counts.keys()))
# 转换RGB到十六进制颜色代码
RGB_colors = []
for rgb_color in RGB_colors_:
hex_color = dict()
hex_color[str(rgb_color)] = '{:02X}{:02X}{:02X}'.format(*rgb_color)
RGB_colors.append(hex_color)
# 按WPS显示 64000 行进行切分
rgb_size = 63999
# 切分块写入不同的Excel文件
for rgb_index, start in enumerate(range(0, len(RGB_colors), rgb_size), start=1):
# 创建一个新的Excel工作簿
wb = Workbook()
ws = wb.active
# 设置表头
ws.cell(row=1, column=1).value = "颜色值"
ws.cell(row=1, column=2).value = "颜色编号"
ws.cell(row=1, column=3).value = "颜色"
# 获取当前切分的块
chunk = RGB_colors[start:start + rgb_size]
for row_index, rgb_color in enumerate(chunk, start=2):
for key, value in rgb_color.items():
hex_color = 'FF' + value
# 第一列显示颜色值
ws.cell(row=row_index, column=1).value = key
# 在Excel中设置单元格颜色,确保使用aRGB格式
fill = PatternFill(start_color=hex_color, end_color=hex_color, fill_type="solid")
ws.cell(row=row_index, column=2).value = hex_color
ws.cell(row=row_index, column=3).fill = fill
# 生成Excel文件名
file_name = f'图片颜色分析统计_{rgb_index}.xlsx'
# 保存Excel文件
wb.save(file_name)
# 输出提示
print(f'{file_name} 文档保存成功!!')
(左右滑动查看完整代码)
结果:
分别通过WPS和Microsoft Office Excel 打开,均成功!
总结
目前这个解决方式,有一个小问题,就是所有的分析数据不在一个Excel文档中,如使用代码强行合到一个文档,就仍会出现上面的问题。
做数据分析的时候,需要手动操作切分的Excel合到一起。
如果同学有更好的方案,欢迎留言,大家一起学习探索。
如果有发现一些Bug,同样欢迎留言,小栈会及时解决。
源码已重新整理:
有兴趣的朋友点个“赞”和“在看”,谢谢支持~!
后台回复“image_color”即可获取!
文章就分享到这儿,喜欢就点个赞吧!