1.微信地球

手机重启后打开微信的一瞬间,会看到一幅有名的图片,上面站着一个 张小龙 。

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789

你可曾想过这样一个问题, 如果上面那个地球转起来会是怎样?

2.效果图

效果简直不要太酷炫,我只能直呼太牛逼!那么这样一个酷炫的操作是怎么做出来的呢?我们接着往下看。

3.素材准备

这里共需要准备三个素材:1. 地球表面素材 ;2. 云图素材 ;3. 微信地球的抠图素材 。

1)地球表面素材

2)云图素材

3)微信地球的抠图素材

4.基本原理

基本的贴图方法在本博前面的文章 《用python实现旋转地球》 中讲过了,具体可以参考下面的链接,这里重点讲 双层素材 的动态效果。云图是灰度图, 白色 地方代表云层厚, 黑色 的地方代表那里云层薄,我们根据颜色设置不同的透明度。

https://blog.csdn.net/xiaorang/article/details/106692489

如果云图与地面的选择速度相同,会显得不自然,我们这里让云层旋转速度比地面旋转速度慢一半,产生 相对运动 的效果。

这样带来的问题是,地球旋转360°后云图只旋转了180°,必须加倍到720°才能实现 连续运动

具体的云层透明度设置,参数需根据实际效果进行调整。

5.GIF压缩

顺便给大家介绍一个比较好用的 压缩GIF 的在线工具,链接如下。

https://www.iloveimg.com/zh-cn/compress-image/compress-gif

直接生成的 GIF动图 有超过传输限制,无法上传,用此工具压缩后文件体积大幅缩小,但图片效果没有肉眼可以察觉的影响。

6.完整代码

分步骤的具体逻辑讲解,请看 《用python实现旋转地球》 这个文章,链接我们在上面已经展示,这里贴一下完整代码。

from PIL import Image, ImageDraw
import math
import numpy as np
import imageio def calcSphereXY2XYZ(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) # z
# print('z:', max(v1z), min(v1z))
v1lat= np.multiply(v1y, math.pi/2) # lat
v0lon= np.arctan2(v1z, -v1x)
v1lon= np.add(v0lon, longOffset) # long
v2lon= np.fmod(v1lon, math.pi*2) # long
return v2lon, v1lat 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 def getPic(a):
# imgBack= Image.open('地球3.jpg')
imgBack= Image.open('世界地球日地图_8K_2.jpg')
imgCloud= Image.open('世界地球云地图_8K.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= calcSphereXY2XYZ(pxList, pyList, h/2, a)
nplon2, nplat2= calcSphereXY2XYZ(pxList, pyList, h/2, a/2)
# nplon, nplat= rotSphere(nplon, nplat, )
npx, npy= calcShpereLatLong2XY(nplon, nplat, width-1, height)
npx2, npy2= calcShpereLatLong2XY(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=[]
str1= '微信地球_mask.png'
img1= Image.new('RGB', (750,1334))
img2= Image.open(str1)
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)
str1= 'temp%03d.png'%i
print(str1)
img1.save(str1)
im = imageio.imread(str1)
frames.append(im)
# img.show()
imageio.mimsave('earth.gif', frames, 'GIF', duration=0.20)

90行代码让微信地球转起来,太酷了!(python实现)的更多相关文章

  1. 通过90行代码学会HTML5 WebSQL的4种基本操作

    Web SQL数据库API是一个独立的规范,在浏览器层面提供了本地对结构化数据的存储,已经被很多现代浏览器支持了. 我们通过一个简单的例子来了解下如何使用Web SQL API在浏览器端创建数据库表并 ...

  2. 蒲公英 · JELLY技术周刊 Vol.17: 90 行代码实现 React Hooks

    蒲公英 · JELLY技术周刊 Vol.17 React Hooks 相信大家都不陌生,自被设计出以来就备受好评,在很多场景中都有极高的使用率,其中原理更是很多大厂面试中的必考题,很多朋友都能够如数家 ...

  3. 5行代码实现微信小程序图片上传与腾讯免费5G存储空间的使用

    本文介绍了如何在微信小程序开发中使用腾讯官方提供的云开发功能快速实现图片的上传与存储,以及介绍云开发的 5G 存储空间的基本使用方法,这将大大提高微信小程序的开发效率,同时也是微信小程序系列教程的视频 ...

  4. iOS Core Image-----十行代码实现微信朋友圈模糊效果

    昨天下午微信的朋友圈着实火了一把,在这之后好多程序员都通过抓包工具看到了原图,但是我却在想,网上说是在移动前端做到的那是怎么做到的呢,经过一些学习,终于掌握了一些Core Image的知识,做出了相应 ...

  5. Python_20行代码实现微信消息防撤回(简易版)

    学习了一下如何用python实现微信消息的防撤回, 主要思路就是: 时时监控微信,将对方发送的消息缓存下来 如果对方撤回了消息,就将该缓存信息发送给文件传输助手 但其实这功能,基本上毫无意义,看到别人 ...

  6. python 7行代码实现微信机器人自动回复

    首先 需要去 图灵 网站注册 获取api_key 先上代码 from wxpy import * bot = Bot() tuling = Tuling(api_key='你的api_key') @b ...

  7. 17行代码解决微信小程序图片延迟加载

    js 页面 Page({ data: { realScrollTop: 0,//页面滚动距离 driveHeight //屏幕高度可初始化设置 }, scroll(e){ if(e.detail.sc ...

  8. 100行代码实现现代版Router

      原文:http://www.html-js.com/article/JavaScript-version-100-lines-of-code-to-achieve-a-modern-version ...

  9. 《第一行代码——Android》

    <第一行代码——Android> 基本信息 作者: 郭霖 丛书名: 图灵原创 出版社:人民邮电出版社 ISBN:9787115362865 上架时间:2014-7-14 出版日期:2014 ...

随机推荐

  1. 05 flask源码剖析之配置加载

    05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...

  2. POJ 1046 Color Me Less 最详细的解题报告

    题目来源:POJ 1046 Color Me Less 题目大意:每一个颜色由R.G.B三部分组成,D=Math.sqrt(Math.pow((left.red - right.red), 2)+ M ...

  3. SQL注入环境的搭建

    使用Phpstudy搭建SQL注入环境: 1.下载phpstudy安装 2.下载sql实验环境 所用环境的代码是一个印度人的开源项目平台.里面包含了基本的各种注入类型,同时又有get和post类型,以 ...

  4. Web For Pentester靶场(xss部分)

    配置 官网:https://pentesterlab.com/ 下载地址:https://isos.pentesterlab.com/web_for_pentester_i386.iso 安装方法:虚 ...

  5. [redis] -- 为什么那么快

    1 完全基于内存 2 数据结构简单,对数据操作也简单 3 只有单线程,避免了不必要的上下文切换,也不存在竞态,不存在多进程或多线程导致的切换而消耗CPU,不用开了各种锁的问题 4 使用多路IO复用模型 ...

  6. consul++ansible+shell批量下发注册node_exporter

    --日期:2020年7月21日 --作者:飞翔的小胖猪  文档功能说明: 文档通过ansible+shell+consul的方式实现批量下发安装Linux操作系统监控的node_exporter软件, ...

  7. A - New Building for SIS

    You are looking at the floor plan of the Summer Informatics School's new building. You were tasked w ...

  8. Mybatis(六)逆向工程generator

    逆向工程概述: MyBatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需要的代 ...

  9. C#使用Halcon连接相机

    (注意:一个相机不能两个软件同时使用在使用vs的时候把halcon关掉,用halcon的时候把vs的关掉切记*一个大坑* 在vs中调用的代码的时候要是用多线程才能显示出来图像不然则录像显示不出来) 1 ...

  10. Debug LinkedList

    Debug LinkedList源码 前置知识 LinkedList基于链表,LinkedList的Node节点定义 成员变量 //链表中元素的数量 transient int size = 0; / ...