妈妈说过在标题栏加感叹号会显得很 low ,但是这的确是我发在 V2EX 第一个项目,不得不激动下。
这是一个 C#项目,可以抓取日本的向日葵 8 号卫星每十分钟更新的的地球照片作为桌面壁纸,逼格爆炸。
效果图如下:

项目地址: https://github.com/bitdust/EarthLiveSharp
使用攻略: https://github.com/bitdust/EarthLiveSharp/issues/3
欢迎大家多提宝贵意见!
点击 start 后会阻塞式的抓取第一张图片,有可能因为网络问题出现未相应的情况。可以尝试在 Settings 里切换图片的获取地址。默认为 cloudinary 的 CDN 。你可以试试切换为 orgin 原始地址即可。
如果实在不行~我去找找有木有更好的(免费) CDN 服务。
对了,这个壁纸的一大逼格在于可以当作桌面时钟来使用:
* 用晨昏线位置估计当地时间;
* 用太阳入射角度估计四季变化即日期。
如下图所示:
 
是不是超赞?
|      1v1024      2015-12-06 21:28:34 +08:00 中国国家航天局发来贺电 | 
|  |      2uuair      2015-12-06 21:37:50 +08:00 可我是 mac 啊……纯支持了! | 
|  |      3aitaii      2015-12-06 21:38:34 +08:00  1 点了 start 就未响应了.. win7 系统 | 
|  |      4miyuki      2015-12-06 21:47:40 +08:00 via Android Earth Federation Space Force 发来贺电 | 
|  |      5bdbai      2015-12-06 21:50:40 +08:00 via iPhone  1 建议把每个类都放在单独的文件内,全挤在 Program.cs 会不好找。 | 
|  |      6wtbhk      2015-12-06 22:56:47 +08:00 点 start 并没有设置壁纸, Win 10 | 
|  |      7Hakusai      2015-12-06 23:05:16 +08:00 发来贺电 | 
|  |      8bitdust OP 终于能回复了 @wtbhk 需要手动设置壁纸的,详见: https://github.com/bitdust/EarthLiveSharp/issues/3 @aitaii 还是未响应吗?看看切下 Settings 里的 Source 为 origin 有效果没 | 
|  |      10h4x3rotab      2015-12-07 08:16:19 +08:00 via iPhone 想移植一个 osx 版 | 
|      11SilentDepth      2015-12-07 09:23:51 +08:00  1 看了实时背景设置方法,这样岂不是让 Windows 在最近数张照片中循环设置为背景,也就是实质上地球照片(对桌面背景来说)并不是按时间顺序刷新的? | 
|  |      12GPU      2015-12-07 09:33:37 +08:00  1 @SilentDepth 刚刚想过了说这个问题 , windows 一直循环这几张图片,这样子不算实时了把 。 @楼主 是不是应该 , 如果有图片更新的时候,删除上一张的,把最新的替换过去呢?样子是不是更好。 | 
|      13xiaozigbd      2015-12-07 09:55:55 +08:00 via iPhone Mark | 
|  |      14vh2h      2015-12-07 10:51:55 +08:00 创意不错,但貌似还有些 bug ,纯支持一下,等完善好了再试试 | 
|  |      15awfe      2015-12-07 11:24:25 +08:00 想法不错! | 
|  |      16bitdust OP  1 @SilentDepth @GPU  由于理解歧义,我还不清楚你们的担心具体是哪个,所以就把自己的考虑全说出来吧: 1.如果你担心桌面背景不会随着图片刷新而刷新,那是多虑了。只要你在第 6 步中点击“全选”按钮的话。那个选中文件夹所有的更新都会被刷到桌面背景上。甚至新增的图片也会被设置成背景。而老的图片的确会被替换掉的。 2.如果你担心以 slideshow 方式展示图片的方法不够实时。这个的确是,我的考虑是这样的:官网的图片刷新间隔是 10 分钟;默认的检查间隔为 7 分钟;桌面的切换间隔是 10 秒钟,默认保存 5 张图片。因此最坏情况,你也能在 10s+7min+50s=8 分钟内看到最新更新的图片。而任何时候你看到的图片都是最近: 5*7min+10min=45min 内更新的! 如果你想要更好的实时性的话,可以调低最大图片数量为 2 ,检查间隔为 5min 。这样任何时候,你都能看到最近 20 分钟内的地球照片啦! 另外,这个工具我是用过一段时间了。一些参数也是总结出来的。为什么要用 slideshow 方式展示?因为这样可以让桌面显得不那么单调。如果有人好奇你的桌面背景是什么的话,你可以让他盯着背景看 10 秒钟,他就会发现:我去,这个地球真的在动诶 o(≧v≦)o~~ 如果他还不相信这是实时图片的话,你就可以跟他普及下晨昏线与当地时间的关系咯。 | 
|      19SilentDepth      2015-12-07 14:29:29 +08:00 @bitdust 明白这个设计的初衷和效果。只是较真一点地想,会出现如下情况: 假设程序 10:00 、 10:11 、 10:22 分别下载得照片 1 、 2 、 3 ,这 3 张照片表示的含义是时间上顺序演进的。 Windows 设置为 1 分钟切换一次( Windows 10 最小设置值),那么就会在 10:21 显示照片 1 , 10:22 显示照片 2 , 10:23 显示照片 3 (刚下载下来的),然后在 10:24 又显示回照片 1 ,给人的感觉就是时间倒退了。 更较真地想,在一个照片刷新周期里,桌面上的地球正在经历着「漫无止境的数十分钟」,想想也是醉了…… 说了一大堆废话,我的 point 就是:为什么不设计为获取到最新照片时自动设置为壁纸(就像必应缤纷桌面那样)?至于「我去,这个地球真的在动诶」的功能,我觉得太小众了 = = | 
|  |      20bitdust OP @SilentDepth  明白了,我会加上这个功能的。而且一间设置桌面壁纸,的确会比现在手动设置的方式更加方便~ | 
|  |      21bdbai      2015-12-07 18:24:49 +08:00 via iPhone  1 @bitdust MVC 适合普通应用,你这个程序的场景并不适合。学做 Windows 应用开发建议上 UWP ,原生的 MVVM 。 | 
|      22me521333      2015-12-07 19:38:23 +08:00 这个时间上确实会出现反复额,上面说的那个获取新图片自动设置壁纸就挺好。 那个,我真的去掉桌面图标盯了十秒,结果我觉得眼睛已经花了分辨不出来地球是不是动了,虽然它真的动了。。。 | 
|      24anguslg      2015-12-08 10:42:02 +08:00 @uuair 给你个曲线救国的方案,使用 dropbox 同步卫星图片, mac 上设置这个同步目录为桌面背景。前提是你得有台一直开机到 windows 23333😂 | 
|      26endpoint      2015-12-08 17:53:29 +08:00 一直都只有一张图片- - | 
|  |      27bitdust OP | 
|  |      28pepsin      2015-12-08 18:30:04 +08:00 ``` require 'net/http' def get_url x, y str = "http://himawari8-dl.nict.go.jp/himawari8/img/D531106/20d/550/2015/12/08/050000_#{x}_#{y}.png" end def run 20.times do |x| 20.times do |y| url = get_url x, y uri = URI.parse(url) req = Net::HTTP::Get.new uri.path res = Net::HTTP.start(uri.host, uri.port, use_ssl: false) do |http| http.request req end file = File.open("himawari_#{x}_#{y}.png", "w+") file.write(res.body) end end end run ``` 简单写了个抓大图的脚本,拼图请自行研究吧~ | 
|  |      29pepsin      2015-12-08 19:00:18 +08:00 require 'net/http' def get_url time, x, y str = "http://himawari8-dl.nict.go.jp/himawari8/img/D531106/20d/550/#{time}0000_#{x}_#{y}.png" end def run time ts = [] 20.times do |x| thread = Thread.new do 20.times do |y| name = "himawari_#{x}_#{y}.png" unless File.exists? name url = get_url time, x, y uri = URI.parse(url) req = Net::HTTP::Get.new uri.path res = Net::HTTP.start(uri.host, uri.port, use_ssl: false) do |http| http.request req end file = File.open(name, "w+") file.write(res.body) end end end ts.push thread end ts.map(&:join) end run "2015/12/08/01" require "cairo" w = 20 h = 20 time = "05" partial_width = 550 surface = Cairo::ImageSurface.new(w * partial_width, h * partial_width) cr = Cairo::Context.new(surface) w.times do |x| h.times do |y| name = "#{time}/himawari_#{x}_#{y}.png" puts name png = Cairo::ImageSurface.from_png(name) cr.set_source(*png) cr.matrix = Cairo::Matrix.identity cr.translate(x * partial_width, y * partial_width) cr.paint() end end cr.target.write_to_png("all.png") | 
|  |      30miao1007      2015-12-08 23:32:39 +08:00 楼上搞 20d 精度要拖垮服务器了,直接 1d 的精度也够用了 ```golang date := time.Now().Add(-21 * time.Minute).In(time.UTC).Format("2006/01/02/1504") url:= "http://himawari8-dl.nict.go.jp/himawari8/img/D531106/1d/550/" + date[0:len(date)-1] + "000_0_0.png" fmt.Print(url) ``` | 
|  |      31bitdust OP | 
|      33SilentDepth      2015-12-09 10:21:15 +08:00 为什么只能看到红红的澳大利亚,不开心 :( | 
|  |      34GPU      2015-12-09 10:25:00 +08:00 @pepsin  ``` require "cairo" w = 20 h = 20 time = "05" partial_width = 550 surface = Cairo::ImageSurface.new(w * partial_width, h * partial_width) cr = Cairo::Context.new(surface) w.times do |x| h.times do |y| name = "#{time}/himawari_#{x}_#{y}.png" puts name png = Cairo::ImageSurface.from_png(name) cr.set_source(*png) cr.matrix = Cairo::Matrix.identity cr.translate(x * partial_width, y * partial_width) cr.paint() end end cr.target.write_to_png("all.png") ``` 執行這段的時候 。去到這裏就 killed 了。 05/himawari_14_3.png Killed | 
|  |      36GPU      2015-12-09 10:33:53 +08:00 我的碼哦。  搞了一張 20d 精度的。 174M 啊啊啊啊 。雙核 CPU 還搞不到,要弄了 10 核的才不卡。 | 
|  |      41GPU      2015-12-09 14:32:49 +08:00 | 
|  |      44miao1007      2015-12-09 15:06:46 +08:00 搞了个 shell 的,使用的 1d 精度,在 RMBP 下效果还可以 <script src="https://gist.github.com/miao1007/54a2bdb012c643e9f826.js"></script> | 
|  |      47pepsin      2015-12-09 15:54:04 +08:00 @GPU 暂时没时间,你自己调整调整呗。我贴个新版的 require 'net/http' require "cairo" def get_url time, x, y str = "http://himawari8-dl.nict.go.jp/himawari8/img/D531106/20d/550/#{time}00_#{x}_#{y}.png" end def merge time puts "Start image process" w = 1 h = 20 partial_width = 550 surface = Cairo::ImageSurface.new(w * partial_width, h * partial_width) cr = Cairo::Context.new(surface) arr = [] w.times do |x| h.times do |y| name = "himawari_#{x}_#{y}.png" arr.push name puts name png = Cairo::ImageSurface.from_png(name) cr.set_source(*png) cr.matrix = Cairo::Matrix.identity cr.translate(x * partial_width, y * partial_width) cr.paint() end end cr.target.write_to_png("#{time.split("/").join("_")}.png") cr.destroy surface.destroy arr.each do |file| # File.delete file end end def run time merge_name = time.split("/").join("_") + ".png" unless File.exists? merge_name ts = [] 1.times do |x| thread = Thread.new do 20.times do |y| name = "himawari_#{x}_#{y}.png" unless File.exists? name url = get_url time, x, y uri = URI.parse(url) req = Net::HTTP::Get.new uri.path res = Net::HTTP.start(uri.host, uri.port, use_ssl: false) do |http| http.request req end file = File.open(name, "w+") file.write(res.body) file.close end end end ts.push thread end ts.map(&:join) sleep 30 end unless File.exists? merge_name merge time end end # 24.times do |hour| # hour = hour.to_s # if hour.length < 2 # hour = "0" + hour # end # 6.times do |minute| # minute = (minute * 10).to_s # if minute.length < 2 # minute = "0" + minute # end # str = "2015/12/01/" + hour + minute # puts str # run str # end # end run "2015/12/01/0000" | 
|  |      50aitaii      2015-12-09 16:52:00 +08:00 1.0 版的是没有启动程序吗。。。。 | 
|  |      51aitaii      2015-12-09 16:54:41 +08:00 看了一下 .7z 的有 .zip 的好像没有呢 | 
|  |      54pepsin      2015-12-09 17:15:28 +08:00 @GPU require 'net/http' require "cairo" def get_url time, x, y str = "http://himawari8-dl.nict.go.jp/himawari8/img/D531106/20d/550/#{time}00_#{x}_#{y}.png" end def merge time puts "Start image process" w = 20 h = 20 partial_width = 550 surface = Cairo::ImageSurface.new(w * partial_width, h * partial_width) cr = Cairo::Context.new(surface) arr = [] h.times do |y| w.times do |x| name = "himawari_#{x}_#{y}.png" arr.push name puts name png = Cairo::ImageSurface.from_png(name) cr.set_source(*png) cr.matrix = Cairo::Matrix.new(1,0,0,1,x * partial_width, y * partial_width) cr.paint() end end cr.target.write_to_png("#{time.split("/").join("_")}.png") cr.destroy surface.destroy arr.each do |file| File.delete file end end def run time merge_name = time.split("/").join("_") + ".png" unless File.exists? merge_name ts = [] 20.times do |x| thread = Thread.new do 20.times do |y| name = "himawari_#{x}_#{y}.png" unless File.exists? name url = get_url time, x, y uri = URI.parse(url) req = Net::HTTP::Get.new uri.path res = Net::HTTP.start(uri.host, uri.port, use_ssl: false) do |http| http.request req end file = File.open(name, "w+") file.write(res.body) file.close end end end ts.push thread end ts.map(&:join) sleep 5 end unless File.exists? merge_name merge time end end 24.times do |hour| hour = hour.to_s if hour.length < 2 hour = "0" + hour end 6.times do |minute| minute = (minute * 10).to_s if minute.length < 2 minute = "0" + minute end str = "2015/12/01/" + hour + minute puts str run str end end # run "2015/12/01/0000" | 
|  |      56GPU      2015-12-09 17:23:57 +08:00 | 
|      57wzqcongcong      2015-12-09 20:13:05 +08:00 学习下然后做个 mac 版的 : ) | 
|  |      58blueset      2015-12-09 22:37:44 +08:00 求哪位大神做一个 Chrome New Tab 版本。 | 
|  |      59Mark24      2015-12-10 11:22:20 +08:00  1 这是我小时候的梦想……真的 | 
|  |      60lqzhgood      2015-12-10 12:06:05 +08:00  1 逼格满满,情怀满满 | 
|  |      61lqzhgood      2015-12-10 12:06:37 +08:00 除了黑色背景 图标有点不搭~~ | 
|      62haiwen      2015-12-10 13:04:44 +08:00  1 赞,已经用上。:) | 
|      63CKboss      2015-12-10 15:58:13 +08:00 import requests import hashlib import time old_md5='' while True: json = requests.get('http://himawari8.nict.go.jp/img/D531106/latest.json') Md5 = hashlib.md5() json = str(json.content).encode('utf-8') Md5.update(json) now_md5=Md5.hexdigest() print(now_md5) if old_md5!=now_md5 : old_md5=now_md5 print(str(json[11:30])) url_2='' for i in range(11,30) : if json[i]==58 : continue elif json[i]==45 or json[i]==32 : url_2=url_2+'/' else : url_2+=str(json[i]-ord('0')) url_1='http://himawari8-dl.nict.go.jp/himawari8/img/D531106/thumbnail/550/' url_3='_0_0.png' url = url_1+url_2+url_3 print(url_1+url_2+url_3) r = requests.get(url) f = open('/home/xxxx/Pictures/壁纸 /Eath/tt.png','bw') f.write(r.content) f.close() print('picture update') else : time.sleep(60) | 
|  |      64pepsin      2015-12-10 17:09:45 +08:00 @GPU https://gist.github.com/pepsin/2332ef243e3285ca68c6 这个才是对的脚本,图片拼接错误也修正了 | 
|  |      68lqzhgood      2015-12-11 10:06:34 +08:00 不知道还有其他卫星开放否 看了一天红红的澳洲…… | 
|  |      69bitdust OP @lqzhgood 不会有了。全世界已发射的搭载可见光相机的地球同步卫星仅此一家。主要用于观测气象的,即使以后还会发射,八成还是太平洋这个位子或者大西洋上空。 | 
|  |      70lqzhgood      2015-12-11 14:31:25 +08:00 @bitdust 观察气象条件为什么要在大洋上空呢~  不应该飘到城市上空做天气预报嘛~ 不懂。 嘎嘎~ 如果可以自定位置,把自己城市居中。 大傍晚的盯着屏幕发呆 上帝视角看着自己灯光闪闪 ~~ 咳咳 该醒来搬砖了…… | 
|  |      71bitdust OP @lqzhgood 这颗是地球同步轨道卫星,所以必须要在赤道上,又是日本发射的,那肯定就是在太平洋赤道上,观测台风比较方便啦。 你在城市上空的话,没法定点的,就看不到这么稳定的图像了~也没有稳定的传输条件的 | 
|  |      72usb      2015-12-11 22:55:04 +08:00 楼主的向日葵 8 号卫星官网的图片看起来都是模糊的云图啊 | 
|  |      73okmemo      2015-12-12 10:51:13 +08:00 请问 WIN10 如何设置呀 | 
|  |      74bitdust OP | 
|      77killerv      2015-12-12 16:48:07 +08:00 不错不错, win10 可以使用 | 
|  |      78usb      2015-12-12 20:56:15 +08:00 明白了,其实是网络问题=_= 可以看到中国诶 | 
|  |      79usb      2015-12-12 20:58:09 +08:00 还有 楼主的下载链接好像下载不了,是需要科学上网? | 
|      81wd0g      2015-12-13 06:21:07 +08:00 要是能实时设置 IDE 编写代码的背景图就好了 | 
|  |      82hjmnoah      2015-12-13 17:50:51 +08:00  1 请问一下 lz 我可以转发你的这个项目到豆瓣吗?(会给出你的 github 链接和你的名字) | 
|  |      84kenshin      2015-12-13 20:10:10 +08:00 via Android 很喜欢 LZ 的壁纸,我是 SimpTab 的作者,关于 SimpTab 的介绍就在这个分支,地址不贴了,免得广告嫌疑。 我想在下个版本中加入这个壁纸源,不清楚是否可以? | 
|  |      85bitdust OP @kenshin 哇~欢迎欢迎 不过希望关注一点: 接口的滥用问题。 这个接口毕竟也不是我自己的,人家也是非赢利的小众网站,所以如果我们给服务端增加的压力太大,可能会被封锁的。所以我推荐你使用些免费的 cdn 做图片缓存。 我个人推荐 cloudinary 的 cdn 服务~用他的 fetch 服务方式抓图简直太合适了。(如果你能用我 readme 里的邀请链接就再好不过了) 对了,如果你需要接口的话,可以去我项目里留个邮箱,我把 api 说明发给你~ | 
|  |      86kenshin      2015-12-13 20:42:41 +08:00 via Android @bitdust  okay , LZ 好勤奋,周末也不闲着。手机党不方便,明天我就去 GitHub 上留言。 | 
|  |      8821grams      2015-12-14 13:57:15 +08:00 求手机版. | 
|  |      89bitdust OP @21grams 想过,然后我发现安卓居然没有切换桌面壁纸的 API 还有就是,手机端实时抓图的话,流量 /电量 比较堪忧。 | 
|  |      9021grams      2015-12-14 15:16:18 +08:00  1 @bitdust 没有吗? 不是有 wallpaperManager 吗?   如果能自定义更新频率的话,流量和电量不就可控了。 | 
|      9229EtwXn6t5wgM3fD      2015-12-15 09:39:05 +08:00 via Android 我大地理专业,看出日期时间日落日出时间太阳直射点太阳高度角~~ | 
|  |      93XiNGRZ      2015-12-15 20:48:33 +08:00  1 | 
|  |      94XiNGRZ      2015-12-15 22:37:01 +08:00 | 
|  |      95XiNGRZ      2015-12-16 01:36:44 +08:00 via Android   Android 也是可行的 | 
|      97ikey      2015-12-16 08:28:58 +08:00 一会安装个试试。 | 
|  |      98XiNGRZ      2015-12-16 09:34:54 +08:00   早安,昨晚一直挂念着 Android 版 demo 的运行状况一夜没睡好。 今天调试一下稳定性和界面,估计晚上可以发 Android 版。 | 
|  |      99amazing4amazing      2015-12-16 12:26:27 +08:00 @XiNGRZ  同样求分享,感觉棒棒哒 | 
|  |      100xyangk      2015-12-16 18:09:50 +08:00  1 我用[python 写了个脚本]( https://github.com/xyangk/EarthLiveSharp),可以在 ubuntu 上运行,每隔十分钟自动更换壁纸 |