标题有点长,也有点怪。前半部分文艺向,后半部分python技术向。目的就是用PIL库得到100张图的拼图(成果图见文末)。
一、百年百图の中国(1900-1999)
看理想有篇文章,叫《100张照片里的中国》(其实是转载自单向街书店的),整理了从1900至1999年,20世纪中国每一年的一张照片。从这些定格的画面里,我们能看到当时的人物面貌和历史痕迹。每张图都有简短的注释,上图便是1960年的照片,备注的文字为:
“全民皆兵是毛泽东在20 世纪 50 年代后期提出的做好反侵略战争准备和全民防卫思想;平时工作与战时准备结合起来,要求国防建设和部队教育训练必须从战争实际出发,必须以人民战争基本理论和要求为基础。”
此外还有“一生诗意千寻瀑,万古人间四月天”、时年12岁的林徽因:
还有齐白石,以前看过《白石老人自述》,自传里涉及其晚年时各种换妻子、生孩子,一家子的辈分、年龄与人物关系非常复杂,至今印象深刻。摘录一段,感兴趣地可以试着绘制出人物关系图谱:(一九三七年,77岁)
六月二十三日,卽阴历五月二十六日,宝珠生了个男孩,这是我的第七子,宝珠生的第四子。我在日记上写道:「二十六日寅时,钟表乃三点二十一分也。生一子,名曰良末,字纪牛,号耋根。此子之八字:戊寅,戊午,丙戌,庚寅,为炎上格,若生于前清时,宰相命也。」我在他的命册上批道:「字以纪牛者,牛,丑也,记丁丑年怀胎也。号以耋根者,八十为耋,吾年八十,尚留此根苗也。」十二月十四日,孙秉声生,是良迟的长子。良迟是我的第四子,宝珠所生的第一子,今年十八岁,娶的是献县纪文达公后裔纪彭年的次女。宝珠今年三十七岁已经有了孙子啦,我们家,人丁可算兴旺哪!美中不足的是:秉声生时,我的第六子良年,乳名叫作小翁子的,病得很重,隔不到十天,十二月二十三日死了,年纔五岁。
言归正常,作为一只喜欢看老照片的吃瓜群众,顺着文中的藤蔓还能摸到诸多摄影集、纪录片。比如“新浪潮祖母”阿涅斯·瓦尔达导演的《北京的星期天》,一部关于 50 年代北京的纪录片。没看错,就是1955年,很早对不对,好奇的可以去B站看看,20分钟左右,不长。 B站:北京的星期天:法国纪录片大师镜头下1955年的彩色北京
二、另类python爬虫和PIL拼图
安利了那么多,该讲到标题后半部分了。在津津有味的阅读看理想的原文不到一半时,便忍不住跑去看了《北京的星期天》,之后也没了耐心继续看篇幅蛮长的原文,再者单纯的下滑页面,依旧无法全局式的看到百年来的变化,于是决定把这100张照片用python爬虫爬取下来,再老样子用PIL库进行拼图,正好10X10的布局,完美。 但想快速写个爬虫爬取照片时发现原文照片是JS异步加载出来的,需要用无界面浏览器selenium PhantomJS,或者执行这部分JS代码,由于一直没怎么用过这俩,而且满脑子想着三下五除二快速爬完了事,还等着美滋滋的拿到拼图好好欣赏。
2.1 另类python爬虫
于是采用将加载后的网页源代码直接复制下来并设置为text,然后直接用lxml进行提取照片url并下载。 (代码为py2.7)
代码语言:javascript复制#! /usr/bin/env python
#coding=utf-8
import requests
import urllib
from lxml import etree
text='''
<!DOCTYPE html>
<!--headTrap<body></body><head></head><html></html>--><html>
<head>
.....................................
.........................................
'''
dom = etree.HTML(text)
try:
img_src=dom.xpath('//img/@data-src')
print len(img_src)#105个
#print img_src
for i in range(4,len(img_src)-1): #前四张和最后一张剔除
try:
print i-3
path="./100Picture/{}.jpg".format(i-3) #下载的图片格式从1开始#1.jpg
urllib.urlretrieve(img_src[i],path)
except:print "image error"
except:print "img_src error!"
2.2 PIL库实现多图拼接
拿到这100张照片后,就可以三板斧呼哧呼哧地耍过去了。
2.2.1 图片重命名
这部分在爬取图片时就已经命名为1.jpg-100.jpg了,所以本次可以跳过,若你手头有其他图片集,可以需要备份后进行如下操作:
代码语言:javascript复制import os
path = r"C:/Users/Administrator/Desktop/100Picture/"
file_list = os.listdir(path)
saved_path = os.getcwd() #C:UsersAdministratorDesktop
os.chdir(path)
i = 1
#打印目录下所有文件: str格式
for file in file_list:
#print file
new_file = "#%s.jpg"% str(i)
os.rename(file, new_file)
i = 1
os.chdir(saved_path)
2.2.2 查看照片格式
由于第三部拼图时需要确保每张缩略图的大小统一,所以必须提前查看所有照片格式,主要是大小,确定长宽下限,本次分别为500和417:
代码语言:javascript复制from PIL import Image
import os, sys
#查看每张图格式、大小
i=1
j=0
while i<101:
try:
im = Image.open("C:/Users/Administrator/Desktop/100Picture/%s.jpg" % i)
print im.format, im.size, im.mode
i =1
j =1
except IOError:
i =1
print j
2.2.3 PIL拼图
所有100张图,均生成为400X400的缩略图,布局成10X10的方式,需要总画布大小为4000X4000。其他照片集可以自行DIY。
代码语言:javascript复制from PIL import Image
import os, sys
mw =400 #每张图大小:长度
#若不想设置成正方形 #例如:wh=300
ms = 10 #列数。每行几张图
msize = mw * ms
toImage = Image.new('RGBA', (4000, 4000)) #画布大小
for y in range(1, 11):
for x in range(1, 11):
#try-except:跳过打不开的图片
try:
fromImage = Image.open("C:/Users/Administrator/Desktop/100Picture/%s.jpg" % str(ms*(y-1) x))
fromImage =fromImage.resize((400, 400), Image.ANTIALIAS)
toImage.paste(fromImage, ((x-1) * mw, (y-1) * mw))
except IOError:
pass
toImage.show()
toImage.save('C:/Users/Administrator/Desktop/100Picture_IM.jpg')
历经千辛万苦,得到最终效果图如下,由左向右、由上向下,从左上角到右下角依次对应1900-1999年的照片:
0-100years_100Picture_IM.jpg
想要全部100张照片的,可去主页简介里的某号后台自取。(侵删) (完)