Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

千图成像:用N张图片拼凑成一张图片。
实现原理:先将所要成像的图片转化成马赛克图片,然后从图库中用对应颜色的图片替换相应色块。


图库中的图片处理:标记图库中每张图片的混合颜色,用于替换目标色块,并记录每张图片的特征用于成像,增加成像质量。

0,起源

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

德莱文

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

图片局部

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

英雄联盟-微博

很久前在刷微博的时候看到了这条,被他给震撼到了,图片是由LOL近千张皮肤图片组合构成的(难道这是用ps做的,还是一张张拼的,应该不可能吧),于是就决定也做一个,随即便展开了行动。搜到了这篇文章,看了下图片的构成,决定先取得所有皮肤的图片再说吧!便又开始了

爬虫

运行环境:Python3.6.5 , pycharm-2018-1-2 , win10

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

愣着干嘛,快往下看

1.爬虫思路

  • 皮肤图片的来源问题,首先到官网去找了找,想到了道聚城皮肤专卖区,其中正好有所有我们需要的图片。

1.爬虫思路

  • 皮肤图片的来源问题,首先到官网去找了找,想到了道聚城皮肤专卖区,其中正好有所有我们需要的图片。
    皮肤图片来源

通过F12锁定图片取得了第一张图片的URL(https://game.gtimg.cn/images/daoju/app/lol/medium/2-122015-9.jpg)
取得URL

  • 以此类推便可取得多个皮肤的URL,发现只有图中红框处不同
    URLS
  • 尝试着改变红框内的数字(玄学),在改变后三位(122015-->122001)时,获得了另一张诺手的皮肤,基本可以确定后三位为皮肤编号,前面的数字为英雄编号,且皮肤编号必须为三位,这一步得感谢这位博主,让我更加确定了这个规律的可行性。(这一步花了好久)
  • 看到这里你可能会有所疑问,为什么不直接正则获取所需图片的URL呢?为什么要大费周章的寻找规律?因为这个翻页式网站比较特殊,在翻页时URL并不会改变,所以无法通过常用方法获取所有皮肤,那估计又有人要提出使用selenium库来模拟人使用浏览器获取所有图片,但是这会造成爬取图片的速度大大下降,只能作为下策(在这过程中了解到了
    八爪鱼,发现其原理类似于selenium,是模拟人操控浏览器,速度也是不容直视,虽然它能爬取近98%的网站),在博主能力有限的情况下选择了寻找规律之旅!
    如果你有好的方法解决这个问题,可以在评论处提出,十分感谢!
  • 接下来在知道了规律的情况下,那么如何获取每个不同英雄的编号呢?在其他博主的引导下,发现LoL资料库中有所有英雄的头像,通过F12的慢慢查找,发现了这个js文件!
    Network

查看其preview,便可得到所有英雄编号,并测试发现可用!比如Ashe艾希的第一个皮肤对应编号按规律应该是22001,所以URL就是

https://game.gtimg.cn/images/daoju/app/lol/medium/2-22001-9.jpg

测试发现确实成功了!

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

preview

  • 好了,到此为止网页分析到此结束了,终于可以编写代码了!

2,代码框架

  • 1,获取英雄编号及皮肤编号(说明:关于皮肤编号并未找到每个英雄皮肤的数量,所以设置成查找所有001到015的图片,当然也可以更多020也行)
  • 2,将编号导入图片URL(https://game.gtimg.cn/images/daoju/app/lol/medium/2-******-9.jpg)中,生成Url_list。
  • 3,根据URL来下载对应图片,并保存到本地。

3,完整代码

<code>import requests
import re
import os

def getHero_data():
    try:
        headers = {
            'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
        }
        url = 'http://lol.qq.com/biz/hero/champion.js'
        r = requests.get(url, headers=headers)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        text = r.text
        hero_id = re.findall(r'"id":"(.*?)","key"', text)
        hero_num = re.findall(r'"key":"(.*?)"', text)
        return hero_id, hero_num
    except:
        return '卧槽,获取英雄编码失败!'

def getUrl(hero_num):
    part1 = 'https://game.gtimg.cn/images/daoju/app/lol/medium/2-'
    part3 = '-9.jpg'
    skin_num = []
    Url_list = []
    for i in range(1, 21):
        i = str(i)
        if len(i) == 1:
            i = '00'+i
        elif len(i) == 2:
            i = '0'+i
        else:
            continue
        skin_num.append(i)
    for hn in hero_num:
        for sn in skin_num:
            part2 = hn + sn
            url = part1 + part2 + part3
            Url_list.append(url)
    print('图片URL获取成功')
    return Url_list

def PicName(hero_id, path):
    pic_name_list = []
    for id in hero_id:
        for i in range(1, 21):
            pic_name = path + id + str(i) + '.jpg'
            pic_name_list.append(pic_name)
    return pic_name_list

def DownloadPic(pic_name_list, Url_list):
    count = 0
    n = len(Url_list)
    try:
        for i in range(n):
            headers = {
                'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
            }
            res = requests.get(Url_list[i], headers=headers).content
            if len(res) < 100:
                count += 1
                print('\r当前进度:{:.2f}%'.format(100*(count/n)), end='')
            else:
                with open(pic_name_list[i], "wb") as f:
                    f.write(res)
                    count += 1
                    print('\r当前进度:{:.2f}%'.format(100*(count/n)), end='')
    except:
        return '卧槽,获取图片失败!'

if __name__ == '__main__':
    input('请输入任意字符开始爬虫:')
    if os.path.exists('D:\LOLimg_wayne\\') == False:
        path = r'D:\LOLimg_wayne\\'
        os.mkdir(path)
        hero_id, hero_num = getHero_data()
        Url_list = getUrl(hero_num)
        pic_name_list = PicName(hero_id, path)
        print('正在下载图片,请稍等。。。')
        print('在' + path + '下查看...')
        DownloadPic(pic_name_list, Url_list)
        print('图片下载完毕')
    else:
        path = r'D:\LOLimg_wayne\\'
        hero_id, hero_num = getHero_data()
        Url_list = getUrl(hero_num)
        pic_name_list = PicName(hero_id, path)
        print('正在下载图片,请稍等。。。')
        print('在' + path + '下查看...')
        DownloadPic(pic_name_list, Url_list)
        print('图片下载完毕')
/<code>

代码写的比较丑,如有看不懂的部分可在评论区提出,我会秒回你的!

/认真脸

好了,到这里我们已经完成了LOL全皮肤的获取,接下来进行最有意思的一步,千图成像!(文末有我爬取到的皮肤图集百度网盘地址)

4,初级阶段我们先使用一款国外的合成软件

软件下载地址

  • 如果打不开,那就搜索“foto-mosaik-edda”下载即可!
Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

Windows用户请选这个


打开后界面是这样的。


Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

第一步创建图库

先选第一步

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

1.1

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

1.2

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

等待一会儿


再选第二步create photo mosaic

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

2.1

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

2.2

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

2.3

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

2.4

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

2.5,弹出警告点确认

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

效果图

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

局部

Python-如何实现千图成像:初级篇(从图片爬取到图片合成)

大吉大利,今晚吃鸡

有时间再分享如何用python实现这个软件的功能………… 如发现错误或看不懂的地方,可在评论区提出,大家一起交流!

结尾

最后多说一句,小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,并在后台私信小编:“01”即可领取。


分享到:


相關文章: