中秋节的月亮怎么拍?不用手机和相机,程序员照样能拍出大片的感觉

说话间,一年一度的中秋节又来到了跟前儿。除了品尝月饼,中秋节最重要的活动大约就是赏月了。一轮高悬月,万念俱清新。古往今来,多少文人墨客借月抒发胸臆,留下了无数吟咏明月的诗词歌赋。现如今,写诗成了贾浅浅们的专享,普通人更喜欢在中秋月圆之夜拍月亮发微博或微信朋友圈与亲朋好友互祝平安。

用手机拍月亮,大概每个人都尝试过吧?效果肯定是令人失望的。当初华为P30 Pro手机号称自带“月亮拍摄模式”,最终也被认为“拍出了不存在的细节,月亮是P上去的”。倘若使用相机拍摄的话,需要配备至少200mm以上的长焦镜头,比如尼康的COOLPIX-P1000相机,拥有3000mm的长焦镜头。除了专业的装备之外,还得选择合适的地点、合适的时机,另外还需要一点点运气。

在这里插入图片描述

不过,对于程序员来说,想要拍出大片的感觉根本需要这么麻烦,甚至,连手机或者相机都不需要。不信?请跟我来一起体验一下吧。

这是一张全月地貌图,古今中外的人们看到的月亮都是这样的,每个摄影师拍到的月亮也是如此。请下载并保存为moon.jpg,后面的代码会用到它。
在这里插入图片描述
如果已经安装了wxgl模块的话(没有的话,请先使用pip install wxgl安装),只用4行就可以把全月地貌图变成了一个三维的月球,可以旋转缩放的那种。uvsphere函数使用经纬度网格生成球,其第1个参数为月球的球心坐标,第2个参数为月球的半径(此处为1),刚才保存的图片成了纹理参数。

import wxgl
import wxgl.glplot as glt

glt.uvsphere((0,0,0), 1, texture=wxgl.Texture('images/moon.jpg'))
glt.show()

在这里插入图片描述
细心的同学会发现,这个月球有问题:初始位置不是月球的正面。没关系,uvsphere函数可以通过ur和vr两个关键字参数设置纹理坐标。下面的代码将水平纹理坐标从默认的(0,1)改为(-0.25,0.75),月球就可以正面朝向我们了。

import wxgl
import wxgl.glplot as glt

texture_moon = wxgl.Texture('images/moon.jpg')

glt.uvsphere((0,0,0), 1, texture=texture_moon, ur=(-0.25,0.75))
glt.show()

在这里插入图片描述
上面的月球默认阳关是从画面的右前方照射过来的,通过重新设置灯光,可以让阳关从正面照射月球。请注意,wxgl坐标系的x轴指向屏幕右方,y轴指向屏幕上方,z轴指向屏幕里面。

import wxgl
import wxgl.glplot as glt

texture_moon = wxgl.Texture('images/moon.jpg')
light_sun = wxgl.SunLight(direction=(0,0,-1))

glt.uvsphere((0,0,0), 1, texture=texture_moon, ur=(-0.25,0.75), light=light_sun)
glt.show()

在这里插入图片描述
现在的月球看起来差不多了。接下来,需要为它找一个合适的背景,就以下面这张夜景图片为例吧,请将其下载并命名为bg_1.jpg,后面的代码会用到它。

在这里插入图片描述
下面这段代码使用quad函数将背景图片放在了月球的后面,看起来像是三维的,但拖拽旋转的话,很容易露出马脚,因此代码中限制了高度角和方位角。如果使用天空盒技术的话,效果会好一些,但对背景图片要求太高,不容易找到合适的图片。

import wxgl
import wxgl.glplot as glt
from PIL import Image

file_bg = 'images/bg_1.jpg'
file_moon = 'images/moon.jpg'

k = 8 # 背景图片高度与月球半径之比,值约大,月球看起来越小
x, y = 6, 4 # 月球在背景中的位置坐标,中心为背景坐标原点

w, h = Image.open(file_bg).size # 获取背景图片宽和高
d = k * w/h # 背景图片宽度
vs = [[-d,k,-1.5], [-d,-k,-1.5], [d,-k,-1.5], [d,k,-1.5]] #  # 背景图片位置

light_base = wxgl.BaseLight()
light_sun = wxgl.SunLight(direction=(0,0,-1))

texture_moon = wxgl.Texture(file_moon)
texture_bg = wxgl.Texture(file_bg, yflip=True)
texcoord_bg = ((0,1), (0,0), (1,0), (1,1)) 

glt.figure(zoom=0.6, elev_range=(0,0), azim_range=(-10,10))
glt.quad(vs, texture=texture_bg, texcoord=texcoord_bg, light=light_base)
glt.uvsphere((x,y,0), 1, texture=texture_moon, ur=(-0.25,0.75), light=light_sun)
glt.show()

改变代码中k值,可以调整月球的大小;改变x和y,可以调整月球在图中的位置。效果如下图所示。

在这里插入图片描述
读懂了这段代码,就可以随意“拍摄”月亮了:想在哪儿拍就在哪儿拍,想拍多大就拍多大。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
增加一个模型几何变换函数,还可以让月亮缓缓地升高转动。

import wxgl
import wxgl.glplot as glt
from PIL import Image

file_bg = 'images/bg_2.jpg'
file_moon = 'images/moon.jpg'

k = 10 # 背景图片高度与月球半径之比,值约大,月球看起来越小
x, y = -7, 0 # 月球在背景中的位置坐标,中心为背景坐标原点

w, h = Image.open(file_bg).size # 获取背景图片宽和高
d = k * w/h # 背景图片宽度
vs = [[-d,k,-1.5], [-d,-k,-1.5], [d,-k,-1.5], [d,k,-1.5]] #  # 背景图片位置

def tf(t):
    """月球移动函数"""
    
    global x, y
    
    t %= 10000
    dx, dy = t/1000, t/3000
    x += dx
    y += dy
    
    return ((dx, dy, 0), )

light_base = wxgl.BaseLight()
light_sun = wxgl.SunLight(direction=(0,0,-1))

texture_moon = wxgl.Texture(file_moon)
texture_bg = wxgl.Texture(file_bg, yflip=True)
texcoord_bg = ((0,1), (0,0), (1,0), (1,1)) 

glt.figure(zoom=0.6, elev_range=(0,0), azim_range=(-10,10))
glt.quad(vs, texture=texture_bg, texcoord=texcoord_bg, light=light_base)
glt.uvsphere((x,y,0), 1, texture=texture_moon, ur=(-0.25,0.75), light=light_sun, transform=tf)
glt.show()

由于CSDN限定上传图片文件大小不能超过5M,gif只能做成这样了。
在这里插入图片描述

掌握了以上要点,这个中秋节就可以在微博和朋友圈随意秀出月亮大片了。

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天元浪子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值