前段时间看到一个新闻:日本74岁老人用Excel画画 栩栩如生!,的确很美,许多网友看了之后感叹“我可能用了假的Excel”。
作为一个码农,虽然缺少绘画的艺术细胞,但特别擅长用程序来处理数字化的信息。说白了,excel也是一个数字化的文件嘛,那么从一个现有的图片,读取每个像素的颜色值,然后再填充到excel对应单元格,不就完成了Excel作画吗?
所干就干,代码如下:
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import PatternFill, Color
from PIL import Image
# 定义常量
IMAGE_FILE = 'starsky.jpg' # 图片的文件名
IMAGE_MAX_SIZE = 400 # 图片长边像素的最大值,如果超出此值,将缩小图片。
img = Image.open(IMAGE_FILE)
print('image\'s type is %s' % img.format)
# 修正图片尺寸
img_width, img_height = img.size
print('image\'s size is (%s, %s)' % (img_width, img_height))
if img_width > IMAGE_MAX_SIZE:
img_height = int(img_height * IMAGE_MAX_SIZE / img_width)
img_width = IMAGE_MAX_SIZE
if img_height > IMAGE_MAX_SIZE:
img_width = int(img_width * IMAGE_MAX_SIZE / img_height)
img_height = IMAGE_MAX_SIZE
img.thumbnail((img_width, img_height)) # 缩小图片尺寸
print('image\'s new size is (%s, %s)' % (img_width, img_height))
# 由于excel对单元格填充色有要求,所以用以下两行代码把图片转换为8位色值
img = img.convert('P')
img = img.convert('RGB')
pix = img.load()
workbook = Workbook()
worksheet = workbook.active
print('begin convert, please waiting...')
# 获取每个像素的色值,并填充到单元格
for row in range(1, img_height):
for col in range(1, img_width):
cell = worksheet.cell(column=col, row=row)
point = pix[col-1, row-1]
color = "FF%02X%02X%02X" % (point[0], point[1], point[2])
cell.fill = PatternFill(patternType='solid', fgColor=Color(rgb=color))
worksheet.row_dimensions[row].height = 6
for col in range(1, img_width):
worksheet.column_dimensions[get_column_letter(col)].width = 1
# 保存生成的excel文件
workbook.save(filename='output.xlsx')
print('Complete.')
下载了一副梵高的“星空”,然后执行上面的程序
"C:\Program Files\Python36\python.exe"
image's type is JPEG
image's size is (658, 483)
image's new size is (400, 293)
begin convert, please waiting...
Complete.
打开生成的“output.xlsx”文件,效果截图如下:
100%比例显示下的马赛克效果
缩小Excel的显示比例查看全图,效果如下:
缩小显示比例的全图效果
以上的实践比较有趣,虽然暂时还没有什么实用价值,但掌握了以下python知识:
- 用“PIL”库读取、处理图片
- 用“openpyxl”库操作Excel文件
另外:
- 日本老爷子是原创作画,的确佩服,博闻广见,才能向高人学习、拓展思路;
- 拥有抽象思维,可以做到“用代码实现所有重复性的信息化操作”。
网友评论