继续挑战
第16题地址mozart.html
- 网页标题是
let me get this straight
,题目内容为空,源码也没有隐藏信息
什么信息也没有肯定就是对这张图做图像处理了。
图片中是乱七八糟的信息,但是貌似七零八落地分布着一些小粉条。再结合标题的意思,应该是要将这些小粉条排成直线。
哦!那就是对图像的每一行重排,将小粉条都排到同一个位置!
from io import BytesIO
import requests
from PIL import Image
with requests.Session() as sess:
sess.auth = ('huge', 'file')
response = sess.get('http://www.pythonchallenge.com/pc/return/mozart.gif').content
img = Image.open(BytesIO(response))
print(img)
<PIL.GifImagePlugin.GifImageFile image mode=P size=640x480 at 0x7F568D4680D0>
图像的高为480,可以看出小粉条的颜色像素个数应该是在480*几的数量级,并且可能会是480的倍数,于是处理一下颜色统计:
colors = []
for count, index in img.getcolors():
colors.append({'index': index, 'count': count, 'color': img.getpalette()[index * 3:(index + 1) * 3]})
height = img.height
colors.sort(key=lambda x: x['count'] % height)
for color in colors:
count = color['count']
if 3 * height <= count <= 7 * height:
print(color, 'count % height =', count % height)
{'index': 195, 'count': 2400, 'color': [255, 0, 255]} count % height = 0
{'index': 66, 'count': 1449, 'color': [102, 153, 51]} count % height = 9
{'index': 11, 'count': 1962, 'color': [51, 0, 0]} count % height = 42
{'index': 139, 'count': 2930, 'color': [153, 153, 153]} count % height = 50
{'index': 133, 'count': 1585, 'color': [153, 102, 153]} count % height = 145
{'index': 61, 'count': 1592, 'color': [153, 102, 51]} count % height = 152
{'index': 52, 'count': 2561, 'color': [0, 51, 51]} count % height = 161
{'index': 9, 'count': 1684, 'color': [9, 9, 9]} count % height = 244
{'index': 131, 'count': 2648, 'color': [51, 102, 153]} count % height = 248
{'index': 103, 'count': 2659, 'color': [153, 153, 102]} count % height = 259
{'index': 46, 'count': 2666, 'color': [0, 0, 51]} count % height = 266
{'index': 55, 'count': 2276, 'color': [153, 51, 51]} count % height = 356
{'index': 138, 'count': 2352, 'color': [102, 153, 153]} count % height = 432
{'index': 125, 'count': 2868, 'color': [51, 51, 153]} count % height = 468
由上筛选出一些颜色,我们挨个查看,发现第一个颜色正好是480*5个像素,并且颜色[255, 0, 255]正好是我们要的那个小粉条的颜色——品红,其颜色index为195。
为了美观,我们统一将小粉条的中间像素移到每行的第一个像素:
symbol_index = 195
img_new = img.copy()
for y in range(img.height):
row_y = img_new.crop((0, y, img.width, y + 1))
row_data = list(row_y.getdata())
symbol_pos = [i for i, p in enumerate(row_data) if p == symbol_index]
row_data = row_data[symbol_pos[2]:] + row_data[:symbol_pos[2]]
row_y.putdata(row_data)
img_new.paste(row_y, (0, y, img.width, y + 1))
img_new
把地址改为romance.html,来到了下一题!