Python3, 19行代码,让微信登录页面地球转起来,涨见识了。
1、引言
小云:鱼哥, 最近在干啥嘞。
小鱼:干活呗, 不然能干啥。
小云:嘿嘿…
小鱼:你这笑的, 怎么 那么 龌(wei)龊(suo)。
小云:没有… 没有…
小鱼:别装了, 无事不登三宝殿的人, 说吧,你有啥事?
小云:果然, 有什么瞒不过鱼哥。
小鱼:那是~ ! 也不看看我是谁~ !
小云:我女神给我发一个动图,我不知道啥意思。
小鱼:啥动图,哪来看看。
小云:就是这个。
小鱼:然后呢,
小云:然后又发了一个图。
小鱼:啥图, 展示下。
小云:鱼哥,你说这是啥意思呢?
小鱼:别慌,待我想一想。
小云:鱼哥,想的怎么样了。
小鱼:别说, 我还真知道了
小云:真的啊, 那快说说, 我的女神想要啥?
小鱼:当然是,旋转的动图了。
小云:可以啊,鱼哥, 没想到,你竟然能get到我女神的想法。
小鱼:… 赶紧制作模型, 赶紧交差,不然赶不上2路公共汽车了。
小云:我女神也没给我期限,你这咋这么着急?
小鱼:… 我的意思,待会 35号(技…师…)该下班了。
小云:…
2、代码实战
2.1 思路
1、 准备素材
要想让地球转起来, 我们首选要做的准备素材。这里需要准备3个素材,如下:
- 地球表面;
- 云图;
- 微信地球抠图;
2、实现原理
很简单,就是利用gif动图来实现的。
具体方法:
- 选择图片上所有的点;
- 计算每一个点对应的经纬度(经纬度是重点);
- 获取经纬度的xy坐标;
- 像素写入到图片中;
- 制作gif动图,实现地球不停旋转。
2.2 示例
这里的难点,有两个,
- 经纬度
- gif制作
所以,我们单独分析这两个方法,然后再进行代码整合。
2.2.1 经纬度
获取经纬度对应的xy坐标
# -*- coding:utf-8 -*-
# @Time : 2023-06-10
# @Author : Carl_DJ
"""
实现原理: 制作一个简单的坐标映射
"""
def calcShpereLatLong2XY(vlon, vlat, width, height):
v3x0=np.multiply(vlon, width/2/math.pi)
v3y0=np.multiply(vlat, height/math.pi)
v3y1=np.add(v3y0, height/2)
v3x2=v3x0.astype(np.integer)
v3y2=v3y1.astype(np.integer)
return v3x2, v3y2
2.2.2 制作gif
代码示例
# -*- coding:utf-8 -*-
# @Time : 2023-06-10
# @Author : Carl_DJ
'''
实现功能:
使用PIL、numpy等库,让微信登录界面的地球转起来。
'''
from PIL import Image, ImageDraw
import math
import numpy as np
import imageio
#获取三维坐标,这里用到的numpy,为了提升计算的速度
def calcXYZ(px, py, maxHeight, longOffset):
v0x= np.array(px)
v0y= np.array(py)
v03= np.subtract(v0x, maxHeight)
v04= np.subtract(v0y, maxHeight)
v1x= np.true_divide(v03, maxHeight)
v1y= np.true_divide(v04, maxHeight)
# print(max(v1x), min(v1x))
v07= np.power(v1x,2)
v08= np.power(v1y,2)
v09= np.add(v07,v08)
v0a= np.subtract(1,v09)
v1z= np.power(v0a,1/2)
# print('z:', max(v1z), min(v1z))
v1lat= np.multiply(v1y, math.pi/2)
v0lon= np.arctan2(v1z, -v1x)
v1lon= np.add(v0lon, longOffset)
v2lon= np.fmod(v1lon, math.pi*2)
return v2lon, v1lat
#获取经纬度对应的xy坐标
def calcLongXY(vlon, vlat, width, height):
v3x0=np.multiply(vlon, width/2/math.pi)
v3y0=np.multiply(vlat, height/math.pi)
v3y1=np.add(v3y0, height/2)
v3x2=v3x0.astype(np.integer)
v3y2=v3y1.astype(np.integer)
return v3x2, v3y2
# 获取像素点,并且把像素点写入到图片中
def getPic(a):
# imgBack= Image.open('地球3.jpg')
imgBack= Image.open('./data/地球日图片.jpg')
imgCloud= Image.open('./data/地球云地图.jpg')
width= imgBack.size[0]
height= imgBack.size[1]
imgBack= imgBack.convert('RGBA')
arrayBack= np.array(imgBack)
arrayCloud= np.array(imgCloud)
circleSize= 508
img2= Image.new('RGBA', (circleSize,circleSize))
img= Image.new('RGBA', (circleSize,circleSize), 'black')
w= img.size[0]
h= img.size[1]
pxList=[]
pyList=[]
for i in range(w):
for j in range(h):
r= math.sqrt((i-w/2)**2+(j-h/2)**2)
if r<circleSize/2:
pxList.append(i)
pyList.append(j)
nplon, nplat= calcXYZ(pxList, pyList, h/2, a)
nplon2, nplat2= calcXYZ(pxList, pyList, h/2, a/2)
# nplon, nplat= rotSphere(nplon, nplat, )
npx, npy= calcXY(nplon, nplat, width-1, height)
npx2, npy2= calcXY(nplon2, nplat2, width-1, height)
color= arrayBack[npy, npx]
color2= arrayCloud[npy2, npx2]
for i in range(len(pxList)):
x= pxList[i]
y= pyList[i]
cc=color[i]
# print(cc)
cc= tuple(cc)
img.putpixel((x,y), cc)
c2= color2[i]
c0= int(c2[0]*1.6)
if c0>255:
c0=255
c_alpha= int(c2[0]*0.9)
c2= (c0,c0,c0,c_alpha)
img2.putpixel((x,y), c2)
r,g,b,a= img2.split()
img.paste(img2, (0,0), mask=a)
return img
if __name__=='__main__':
frames=[]
str_path1= './data/微信地图.png'
img1= Image.new('RGB', (750,1300))
img2= Image.open(str_path1)
for i in range(0, 720, 12):
a= -i*math.pi/ 180
img= getPic(a)
img1.paste(img,(122,424))
r,g,b,alpha=img2.split()
img1.paste(img2, (0,0), mask=alpha)
str_path1= 'Demo.png'%i
img1.save(str_path1)
im = imageio.imread(str_path1)
frames.append(im)
# img.show()
imageio.mimsave('earth.gif', frames, 'GIF', duration=0.20)
运行结果:
小云:鱼哥,运行结果是啥样的呢?
小鱼:嘿嘿,这里留个彩蛋, 你自己运行下代码, 看看呗。
小云:鱼哥,好事做到底啊。 你就直接把图放上来呗。
小鱼:那不行,不能什么都等着我喂到嘴里的。
小云:那我来运行看看。
3、总结
看到这里,今天的分享就到这里 。
其实我们来回想一下,其实通篇的难点就2个,即:
- 1、如何获取经纬度的xy坐标,并且把像素写入到图片中;
- 2、GFI图片制作;
但是,针对GIF图片的制作, 你可以参照小鱼的这篇博文:
- 《Python3,5行代码,制作Gif动图,太简单了。》
关于 获取坐标经纬度, 你也可以参照小鱼的这篇博文:
- 《Python3,19行代码,我把她的照片写入到Excel中,2022年伊始,她终于被我感动了。》
- 《Python3,为了给女神暗送秋波,我默默的写了一个图片字符画生成器,真香。》
所以,看过这几篇,在回来从新看这段代码, 是不是就很简单了呢 。
我是小鱼:
- CSDN 博客专家;
- 阿里云 专家博主;
- 51CTO 博客专家;
- 51认证讲师;
- 认证金牌面试官;
- 职场培训规划师;
- 多个国内主流技术社区的认证专家博主;
- 多款主流产品(阿里云等)测评一、二等奖获得者;
我是小鱼,关注我,带你学习更多更专业更前沿的Python技术。
- 点赞
- 收藏
- 关注作者
评论(0)