diff --git a/2018-10-01-macos-dynamic-desktop.md b/2018-10-01-macos-dynamic-desktop.md
new file mode 100644
index 0000000..896354a
--- /dev/null
+++ b/2018-10-01-macos-dynamic-desktop.md
@@ -0,0 +1,728 @@
+---
+title: macOS Dynamic Desktop
+author: Mattt
+category: ""
+excerpt: >
+ Dark Mode is one of the most popular additions to macOS ---
+ especially among us developer types.
+ If you triangulate between that and Night Shift,
+ introduced a couple of years prior,
+ you get the Dynamic Desktop feature, new in Mojave.
+status:
+ swift: 4.2
+---
+
+---
+title: "macOS 动态桌面"
+author: Mattt
+translator: saitjr
+category: ""
+excerpt: >
+ Dark Mode 可谓是 macOS 最受欢迎的特性之一了 —— 尤其是对于你我这样的开发者来说。过去几年,和这个特性旗鼓相当的要数 Night Shift,而在 Mojave 当中,推出了全新的 Dynamic Desktop。
+status:
+ swift: 4.2
+---
+
+Dark Mode is one of the most popular additions to macOS ---
+especially among us developer types,
+who tend towards light-on-dark color themes in text editors
+and appreciate this new visual consistency across the system.
+
+Dark Mode(深色模式)可谓是 macOS 最受欢迎的特性之一了 —— 尤其是对于你我这样的开发者来说。我们不仅喜欢文本编辑器是暗色的主题,还很看中整个系统色调的一致性。
+
+A couple of years back, there was similar fanfare for Night Shift,
+which helped to reduce eye strain
+from hacking late into the night (or early in the morning, as it were).
+
+过去几年,和这个特性旗鼓相当的要数 Night Shift(夜览),它主要是在日夜更替的时候减少对眼睛的劳损。
+
+If you triangulate from those two macOS features,
+you get Dynamic Desktops, also new in Mojave.
+Now when you go to "System Preferences > Desktop & Screen Saver",
+you have the option to select a "Dynamic" desktop picture
+that changes throughout the day, based on your location.
+
+纵观这两个功能,Dynamic Desktop(动态桌面)也就呼之欲出了,当然这也是 Mojave 的新特性之一。进入“System Preferences(系统偏好设置)> Desktop & Screen Saver(桌面与屏幕保护程序)”并且选择“Dynamic(动态)”,就能得到一个基于地理位置且全天候动态变化的壁纸。
+
+{% asset desktop-and-screen-saver-preference-pane.png %}
+
+The result is subtle and delightful.
+Having a background that tracks the passage of time
+makes the desktop feel alive;
+in tune with the natural world.
+(If nothing else,
+it makes for a lovely visual effect when switching dark mode on and off)
+
+效果不仅微妙,而且让人愉悦。桌面仿佛被赋予了生命,能随着时间的推移而变化;符合自然规律。(不出意外的话,结合 dark mode 的切换,还会有讨喜的特效)
+
+_But how does it work, exactly?_
+That's the question for this week's NSHipster article.
+
+_这到底是如何实现的呢?_
+这便是本周 NSHipster 讨论的问题。
+
+The answer involves a deep dive into image formats,
+a little bit of reverse-engineering
+and even some spherical trigonometry.
+
+答案会深入探究图片格式,同时涉及一些逆向工程以及球面三角学相关的内容。
+
+---
+
+The first step to understanding how Dynamic Desktop works
+is to get hold of a dynamic image.
+
+理解 Dynamic Desktop 第一步,就是要找到这些动态图片。
+
+If you're running macOS Mojave
+open Finder,
+select "Go > Go to Folder..." (⇧⌘G),
+and enter "/Library/Desktop Pictures/".
+
+在 macOS Mojave 系统下,打开 Finder(访达),选择“Go(前往)> Go to Folder...(前往文件夹...)” (⇧⌘G),输入“/Library/Desktop Pictures/”。
+
+{% asset go-to-library-desktop-pictures.png %}
+
+In this directory,
+you should find a file named "Mojave.heic".
+Double-click it to open it in Preview.
+
+在这个目录下,可以找到名为“Mojave.heic”的文件。双击通过 Preview(预览)打开。
+
+{% asset mojave-heic.png %}
+
+In Preview,
+the sidebar shows a list of thumbnails numbered 1 through 16,
+each showing a different view of the desert scene.
+
+在预览中,左边栏会显示从 1 ~ 16 的缩略图,每张都是不同状态的沙漠图。
+
+{% asset mojave-dynamic-desktop-images.png %}
+
+If we select "Tools > Show Inspector" (⌘I),
+we get some general information about what we're looking at:
+
+如果选择“Tools(工具)> Show Inspector(显示检查器)”(⌘I),可以看到更为详细的信息,如下图所示:
+
+{% asset mojave-heic-preview-info.png %}
+
+Unfortunately, that's about all Preview gives us
+(at least at the time of writing).
+If we click on the next panel over, "More Info Inspector",
+we don't learn a whole lot more about our subject:
+
+不幸的是,这些就是预览所展示的全部信息了(截至发稿前)。即使点击旁边的“More Info Inspector(更多信息检查器)”,我们也只是能得到下面这个表格,其余的无从得知:
+
+| | |
+| ------------ | ---------- |
+| Color Model | RGB |
+| Depth: | 8 |
+| Pixel Height | 2,880 |
+| Pixel Width | 5,120 |
+| Profile Name | Display P3 |
+
+{% info %}
+
+The `.heic` file extension corresponds to image containers
+encoded using the HEIF,
+or High-Efficiency Image File Format
+(which is itself based on HEVC,
+or High-Efficiency Video Compression ---
+also known as H.265 video).
+For more information, check out
+[WWDC 2017 Session 503 "Introducing HEIF and HEVC"](https://developer.apple.com/videos/play/wwdc2017/503/)
+
+后缀 `.heic` 表示图片容器采用 HFIF(High-Efficiency Image File Format)编码,即高效率图档格式(这种格式基于 HEVC(High-Efficiency Video Compression),即高效率视频压缩,也就是 H.265)。更多信息,可以参考 [WWDC 2017 Session 503 "Introducing HEIF and HEVC"](https://developer.apple.com/videos/play/wwdc2017/503/)
+
+{% endinfo %}
+
+If we want to learn more,
+we'll need to roll up our sleeves
+and get our hands dirty with some low-level APIs.
+
+想要获得更多的数据,我们还需要脚踏实地,真真切切的深入底层 API。
+
+## Digging Deeper with CoreGraphics
+
+## 利用 CoreGraphics 一探究竟
+
+Let's start our investigation by creating a new Xcode Playground.
+For simplicity, we can hard-code a URL to the "Mojave.heic" file on our system.
+
+第一步先创建 Xcode Playground。简单起见,我们将“Mojave.heic”文件路径硬编码到代码中。
+
+```swift
+import Foundation
+import CoreGraphics
+
+// macOS 10.14 Mojave Required
+let url = URL(fileURLWithPath: "/Library/Desktop Pictures/Mojave.heic")
+```
+
+Next, create a `CGImageSource`,
+copy its metadata,
+and enumerate over each of its tags:
+
+然后,创建 `CGImageSource`,拷贝元数据并遍历全部标签:
+
+```swift
+let source = CGImageSourceCreateWithURL(url as CFURL, nil)!
+let metadata = CGImageSourceCopyMetadataAtIndex(source, 0, nil)!
+let tags = CGImageMetadataCopyTags(metadata) as! [CGImageMetadataTag]
+for tag in tags {
+ guard let name = CGImageMetadataTagCopyName(tag),
+ let value = CGImageMetadataTagCopyValue(tag)
+ else {
+ continue
+ }
+
+ print(name, value)
+}
+```
+
+When we run this code, we get two results:
+`hasXMP`, which has a value of `"True"`,
+and `solar`, which has a decidedly less understandable value:
+
+运行这段代码,会得到两个值:一个是 `hasXMP`,值为 `"True"`,另一个是 `solar`,它的值是一串看不大懂的数据:
+
+```
+YnBsaXN0MDDRAQJSc2mvEBADDBAUGBwgJCgsMDQ4PEFF1AQFBgcICQoLUWlRelFh
+UW8QACNAcO7vOubr3yO/1e+pmkOtXBAB1AQFBgcNDg8LEAEjQFRxqCKOFiAjwCR6
+waUkDgHUBAUGBxESEwsQAiNAVZV4BI4c+CPAEP2uFrMcrdQEBQYHFRYXCxADI0BW
+tALKmrjwIz/2ObLnx6l21AQFBgcZGhsLEAQjQFfTrJlEjnwjQByrLle1Q0rUBAUG
+Bx0eHwsQBSNAWPrrmI0ISCNAKiwhpSRpc9QEBQYHISIjCxAGI0BgJff9KDpyI0BE
+NTOsilht1AQFBgclJicLEAcjQGbHdYIVQKojQEq3fAg86lXUBAUGBykqKwsQCCNA
+bTGmpC2YRiNAQ2WFOZGjntQEBQYHLS4vCxAJI0BwXfII2B+SI0AmLcjfuC7g1AQF
+BgcxMjMLEAojQHCnF6YrsxcjQBS9AVBLTq3UBAUGBzU2NwsQCyNAcTcSnimmjCPA
+GP5E0ASXJtQEBQYHOTo7CxAMI0BxgSADjxK2I8AoalieOTyE1AQFBgc9Pj9AEA0j
+QHNWsnnMcWIjwEO+oq1pXr8QANQEBQYHQkNEQBAOI0ABZpkFpAcAI8BKYGg/VvMf
+1AQFBgdGR0hAEA8jQErBKblRzPgjwEMGElBIUO0ACAALAA4AIQAqACwALgAwADIA
+NAA9AEYASABRAFMAXABlAG4AcAB5AIIAiwCNAJYAnwCoAKoAswC8AMUAxwDQANkA
+4gDkAO0A9gD/AQEBCgETARwBHgEnATABOQE7AUQBTQFWAVgBYQFqAXMBdQF+AYcB
+kAGSAZsBpAGtAa8BuAHBAcMBzAHOAdcB4AHpAesB9AAAAAAAAAIBAAAAAAAAAEkA
+AAAAAAAAAAAAAAAAAAH9
+```
+
+### Shining Light on Solar
+
+### 太阳之光
+
+Most of us would look at that wall of text
+and quietly close the lid of our MacBook Pro.
+But, as some of you surely noticed,
+this text looks an awful lot like it's
+[Base64-encoded](https://en.wikipedia.org/wiki/Base64).
+
+大多数人看到这串文字,就会默默合上 MacBook Pro,大呼告辞。但一定有人发现,这串文字非常像 [Base64 编码](https://en.wikipedia.org/wiki/Base64) 的杰作。
+
+Let's test out our hypothesis in code:
+
+让我们来验证一下这个假设:
+
+```swift
+if name == "solar" {
+ let data = Data(base64Encoded: value)!
+ print(String(data: data, encoding: .ascii))
+}
+```
+
+
+bplist00Ò\u{01}\u{02}\u{03}...
+
+
+What's that?
+`bplist`, followed by a bunch of garbled nonsense?
+
+这又是什么?
+`bplist` 后面接了一串乱码?
+
+By golly, that's the
+[file signature](https://en.wikipedia.org/wiki/File_format#Magic_number)
+for a [binary property list](https://en.wikipedia.org/wiki/Property_list).
+
+天哪,原来这是[二进制属性列表](https://en.wikipedia.org/wiki/Property_list)的[文件签名](https://en.wikipedia.org/wiki/File_format#Magic_number)。
+
+Let's see if `PropertyListSerialization` can make any sense of it...
+
+利用 `PropertyListSerialization` 来看看呢...
+
+```swift
+if name == "solar" {
+ let data = Data(base64Encoded: value)!
+ let propertyList = try PropertyListSerialization
+ .propertyList(from: data,
+ options: [],
+ format: nil)
+ print(propertyList)
+}
+```
+
+```
+(
+ ap = {
+ d = 15;
+ l = 0;
+ };
+ si = (
+ {
+ a = "-0.3427528387535028";
+ i = 0;
+ z = "270.9334057827345";
+ },
+ ...
+ {
+ a = "-38.04743388682423";
+ i = 15;
+ z = "53.50908581251309";
+ }
+ )
+)
+```
+
+_Now we're talking!_
+
+_清晰多了!_
+
+We have two top-level keys:
+
+首先有两个一级键:
+
+The `ap` key corresponds to
+a dictionary containing integers for the `d` and `l` keys.
+
+`ap` 键对应的值是包含 `d` 和 `l` 两个键的字典,它们的值都是整型。
+
+The `si` key corresponds to
+an array of dictionaries with integer and floating-point values.
+Of the nested dictionary keys,
+`i` is the easiest to understand:
+incrementing from 0 to 15,
+they're the index of the image in the sequence.
+It'd be hard to guess `a` and `z` without any additional information,
+but they turn out to represent the altitude (`a`) and azimuth (`z`)
+of the sun in the corresponding pictures.
+
+`si` 键对应的值是包含多个字典的数组,字典中有整型,也有浮点型的值。在嵌套的字典中,`i` 最容易理解:它从 0 一直递增到 15,这表示的是图片序列的下标。在没有更多信息的情况下,很难猜测 `a` 与 `z` 的含义,其实它们表示相应图片中太阳的高度(`a`)和方位角(`z`)。
+
+### Calculating Solar Position
+
+### 计算太阳的位置
+
+At the time of writing,
+those of us in the northern hemisphere
+are settling into the season of autumn
+and its shorter, colder days,
+whereas those of us in the southern hemisphere
+are gearing up for hotter and longer days.
+The changing of the seasons reminds us that
+the duration of a solar day depends where you are on the planet
+and where the planet is in its orbit around the sun.
+
+就在我落笔之时,身处北半球的人正在进入秋季,白昼变短,气温变低,而南半球的人却经历着白昼变长,气温变高。季节的变化告诉我们,日照的时长取决于你在星球上的位置,以及星球绕太阳的轨道。
+
+The good news is that astronomers can tell you ---
+with perfect accuracy ---
+where the sun is in the sky for any location or time.
+The bad news is that
+the necessary calculations are
+[complicated](https://en.wikipedia.org/wiki/Position_of_the_Sun)
+to say the least.
+
+可喜的是,天文学家能告诉你 —— 而且相当准确 —— 太阳在天空中的位置或时间。不可贺的是,这其中的计算十分[复杂](https://en.wikipedia.org/wiki/Position_of_the_Sun)。
+
+Honestly, we don't really understand it ourselves,
+and are pretty much just porting whatever code we manage to find online.
+After some trial and error,
+we were able to arrive at
+[something that seems to work](https://github.com/NSHipster/DynamicDesktop/blob/master/SolarPosition.playground)
+(PRs welcome!):
+
+但老实讲,我们并不用过分深究它,在网上能找到相关的代码。经过不断的试错,[它们就能为我所用](https://github.com/NSHipster/DynamicDesktop/blob/master/SolarPosition.playground)(欢迎 PR!):
+
+```swift
+import Foundation
+import CoreLocation
+
+// Apple Park, Cupertino, CA
+let location = CLLocation(latitude: 37.3327, longitude: -122.0053)
+let time = Date()
+
+let position = solarPosition(for: location, at: time)
+let formattedDate = DateFormatter.localizedString(from: time,
+ dateStyle: .medium,
+ timeStyle: .short)
+print("Solar Position on \(formattedDate)")
+print("\(position.azimuth)° Az / \(position.elevation)° El")
+```
+
+
+Solar Position on Oct 1, 2018 at 12:00
+180.73470025840783° Az / 49.27482549913847° El
+
+
+At noon on October 1, 2018,
+the sun shines on Apple Park from the south,
+about halfway between the horizon and directly overhead.
+
+2018 年 10 月 1 日中午,太阳从南面照射在 Apple Park,大约处于地平线中间,直射头顶。
+
+If track the position of the sun over an entire day,
+we get a sinusoidal shape reminiscent of the Apple Watch "Solar" face.
+
+如果绘制出太阳一天的位置,我们可以得到一个正弦曲线,这不禁让人联想到 Apple Watch 的“太阳表盘”。
+
+{% asset solar-position-watch-faces.jpg %}
+
+### Extending Our Understanding of XMP
+
+### 扩展对 XMP 的理解
+
+Alright, enough astronomy for the moment.
+Let's ground ourselves in something much more banal:
+_de facto_ XML metadata standards.
+
+好吧,天文学到此结束。接下来是一个乏味的过程:_摆在眼前的_ XML 元数据。
+
+Remember the `hasXMP` metadata key from before?
+Yeah, _that_.
+
+还记得之前的元数据键 `hasXMP` 吗?对,_就是它_。
+
+XMP,
+or Extensible Metadata Platform,
+is a standard format for tagging files with metadata.
+What does XMP look like?
+Brace yourself:
+
+XMP(Extensible Metadata Platform),即可扩展元数据平台,是一种使用元数据标记文件的标准格式。XMP 长什么样呢?请打起精神来:
+
+```swift
+let xmpData = CGImageMetadataCreateXMPData(metadata, nil)
+let xmp = String(data: xmpData as! Data, encoding: .utf8)!
+print(xmp)
+```
+
+```xml
+
+
+
+
+
+
+
+
+
+```
+
+_Yuck._
+
+_呕。_
+
+But it's a good thing that we checked.
+We'll need to honor that `apple_desktop` namespace
+to make our own Dynamic Desktop images work correctly.
+
+不过也幸好我们检查了一下。之后想要成功自定义 Dynamic Desktop,还得仰仗 `apple_desktop` 命名空间。
+
+Speaking of, let's get started on that.
+
+既然如此,就开始吧。
+
+## Creating Our Own Dynamic Desktop
+
+## 创建自定义 Dynamic Desktop
+
+Let's create a data model to represent a Dynamic Desktop:
+
+首先,创建一个数据模型来表示 Dynamic Desktop:
+
+```swift
+struct DynamicDesktop {
+ let images: [Image]
+
+ struct Image {
+ let cgImage: CGImage
+ let metadata: Metadata
+
+ struct Metadata: Codable {
+ let index: Int
+ let altitude: Double
+ let azimuth: Double
+
+ private enum CodingKeys: String, CodingKey {
+ case index = "i"
+ case altitude = "a"
+ case azimuth = "z"
+ }
+ }
+ }
+}
+```
+
+Each Dynamic Desktop comprises an ordered sequence of images,
+each of which has image data, stored in a `CGImage` object,
+and metadata, as discussed before.
+We adopt `Codable` in the `Metadata` declaration
+in order for the compiler to automatically synthesize conformance.
+We'll take advantage of that when it comes time
+to generate the Base64-encoded binary property list.
+
+如前文所述,每个 Dynamic Desktop 都由一个有序的图片序列构成,每个图片又包含存储在 `CGImage` 对象中的图片数据和元数据。`Metadata` 采用 `Codable` 类型,是为了编译器自动合成相关函数。我们能在生成 Base64 编码的二进制属性列表时感受到它的优势。
+
+### Writing to an Image Destination
+
+### 写入图片目标
+
+First, create a `CGImageDestination`
+with a specified output URL.
+The file type is `heic` and the source count
+is equal to the number of images to be included.
+
+首先,创建一个指定输出 URL 的 `CGImageDestination`。文件类型为 `heic`,资源数量即需要包含的图片张数。
+
+```swift
+guard let imageDestination = CGImageDestinationCreateWithURL(
+ outputURL as CFURL,
+ AVFileType.heic as CFString,
+ dynamicDesktop.images.count,
+ nil
+ )
+else {
+ fatalError("Error creating image destination")
+}
+```
+
+Next, enumerate over each image in the dynamic desktop object.
+By using the `enumerated()` method,
+we also get the current `index` for each loop
+so that we can set the image metadata on the first image:
+
+接着,遍历动态桌面对象中的全部图片。通过 `enumerated()` 方法,我们还能获取到当前 `index`,这样就可以在第一张图片上设置图片元数据:
+
+```swift
+for (index, image) in dynamicDesktop.images.enumerated() {
+ if index == 0 {
+ let imageMetadata = CGImageMetadataCreateMutable()
+ guard let tag = CGImageMetadataTagCreate(
+ "http://ns.apple.com/namespace/1.0/" as CFString,
+ "apple_desktop" as CFString,
+ "solar" as CFString,
+ .string,
+ try! dynamicDesktop.base64EncodedMetadata() as CFString
+ ),
+ CGImageMetadataSetTagWithPath(
+ imageMetadata, nil, "xmp:solar" as CFString, tag
+ )
+ else {
+ fatalError("Error creating image metadata")
+ }
+
+ CGImageDestinationAddImageAndMetadata(imageDestination,
+ image.cgImage,
+ imageMetadata,
+ nil)
+ } else {
+ CGImageDestinationAddImage(imageDestination,
+ image.cgImage,
+ nil)
+ }
+}
+```
+
+Aside from the unrefined nature of Core Graphics APIs,
+the code is pretty straightforward.
+The only part that requires further explanation is the call to
+`CGImageMetadataTagCreate(_:_:_:_:_:)`.
+
+除了较为繁杂的 Core Graphics API 以外,代码可以说非常直观了。唯一需要进一步解释的只有 `CGImageMetadataTagCreate(_:_:_:_:_:)`。
+
+Because of a mismatch between how image and container metadata are structured
+and how they're represented in code,
+we have to implement `Encodable` for `DynamicDesktop` ourselves:
+
+由于图片与元数据容器的结构、代码的表现形式均不同,所以我们不得不为 `DynamicDesktop` 实现 `Encodable` 协议:
+
+```swift
+extension DynamicDesktop: Encodable {
+ private enum CodingKeys: String, CodingKey {
+ case ap, si
+ }
+
+ private enum NestedCodingKeys: String, CodingKey {
+ case d, l
+ }
+
+ func encode(to encoder: Encoder) throws {
+ var keyedContainer =
+ encoder.container(keyedBy: CodingKeys.self)
+
+ var nestedKeyedContainer =
+ keyedContainer.nestedContainer(keyedBy: NestedCodingKeys.self,
+ forKey: .ap)
+
+ // FIXME: Not sure what `l` and `d` keys indicate
+ try nestedKeyedContainer.encode(0, forKey: .l)
+ try nestedKeyedContainer.encode(self.images.count, forKey: .d)
+
+ var unkeyedContainer =
+ keyedContainer.nestedUnkeyedContainer(forKey: .si)
+ for image in self.images {
+ try unkeyedContainer.encode(image.metadata)
+ }
+ }
+}
+```
+
+With that in place,
+we can implement the aforementioned `base64EncodedMetadata()` method like so:
+
+有了这个,就可以实现之前代码中提到的 `base64EncodedMetadata()` 方法了:
+
+```swift
+extension DynamicDesktop {
+ func base64EncodedMetadata() throws -> String {
+ let encoder = PropertyListEncoder()
+ encoder.outputFormat = .binary
+
+ let binaryPropertyListData = try encoder.encode(self)
+ return binaryPropertyListData.base64EncodedString()
+ }
+}
+```
+
+Once the for-in loop is exhausted,
+and all images and metadata are written,
+we call `CGImageDestinationFinalize(_:)` to finalize the image source
+and write the image to disk.
+
+当 for-in 循环执行完,也就表明所有图片和元数据均被写入,我们可以调用 `CGImageDestinationFinalize(_:)` 方法终止图片源,并将图片写入磁盘。
+
+```swift
+guard CGImageDestinationFinalize(imageDestination) else {
+ fatalError("Error finalizing image")
+}
+```
+
+If everything worked as expected,
+you should now be the proud owner of a brand new Dynamic Desktop.
+Nice!
+
+如果一切顺利,就可以为重新定义 Dynamic Desktop 的自己而感到骄傲了。
+棒!
+
+---
+
+We love the Dynamic Desktop feature in Mojave,
+and are excited to see the same proliferation of them
+that we saw when wallpapers hit the mainstream with Windows 95.
+
+我们非常喜欢 Mojave 的 Dynamic Desktop 特性,并且也很欣慰看到它仿佛重现了 Windows 95 壁纸进入主流市场时的辉煌。
+
+If you're so inclined,
+here are a few ideas for where to go from here:
+
+如果你也这样想,下面还有些想法可供参考:
+
+### Automatically Generating a Dynamic Desktop from Photos
+
+### 照片自动生成 Dynamic Desktop
+
+It's mind-blowing to think that something as transcendent as
+the movement of celestial bodies
+can be reduced to a system of equations with two inputs:
+time and place.
+
+让人振奋的是,天体运动这样高不可攀的研究,竟然可以简化用二元方程来表达:时间与位置。
+
+In the example before,
+this information is hard-coded,
+but you could ostensibly extract that information
+from images automatically.
+
+在之前的例子中,这部分信息都是硬编码的,但其实它们可以通过读取图片数据来自动获取。
+
+By default,
+the camera on most phones captures
+[Exif metadata](https://en.wikipedia.org/wiki/Exif)
+each time a photo is snapped.
+This metadata can include the time which the photo was taken
+and the GPS coordinates of the device at the time.
+
+默认情况下,绝大部分手机的相机都会捕获拍摄时的 [Exif 元数据](https://en.wikipedia.org/wiki/Exif)。元数据包含了照片拍摄的时间,以及当时设备的 GPS 坐标。
+
+By reading time and location information directly from image metadata,
+you can automatically determine solar position
+and simplify the process of generating a Dynamic Desktop
+from a series of photos.
+
+通过读取元数据中的时间与位置信息,能自动获取太阳的位置,那么从一系列图片中生成 Dynamic Desktop 也就顺理成章了。
+
+### Shooting a Time Lapse on Your iPhone
+
+### iPhone 上的延时摄影
+
+Want to put your new iPhone XS to good use?
+(Or more accurately,
+"Want to use your old iPhone for something productive
+while you procrastinate selling it?")
+
+想要好好利用手上全新的 iPhone Xs 吗?(更确切的说,“在纠结卖不卖旧 iPhone 的时候,可以先用它来做些有创意的事?”)
+
+Mount your phone against a window,
+plug it into a charger,
+set the Camera to Timelapse mode,
+and hit the "Record" button.
+By extracting key frames from the resulting video,
+you can make your very own _bespoke_ Dynamic Desktop.
+
+将手机充上电,摆在窗前,打开相机的延时摄影模式,点击“拍摄”按钮。从最后的视频中选出一些关键帧,就可以制作 _专属_ Dynamic Desktop 了。
+
+You might also want to check out
+[Skyflow](https://itunes.apple.com/us/app/skyflow-time-lapse-shooting/id937208291?mt=8)
+or similar apps that more easily allow you to
+take still photos at predefined intervals.
+
+当然,你可以看看 [Skyflow](https://itunes.apple.com/us/app/skyflow-time-lapse-shooting/id937208291?mt=8) 这类应用,它能设置时间间隔来拍摄静态图片。
+
+### Generating Landscapes from GIS Data
+
+### 通过 GIS 数据打造风景
+
+If you can't stand to be away from your phone for an entire day (sad)
+or don't have anything remarkable to look (also sad),
+you could always create your own reality (sounds sadder than it is).
+
+如果你无法忍受手机一整天不在身边(伤心),又或者没什么标志性景象值得拍摄(依然伤心),你还可以创造一个属于自己的世界(这比现实本身还要令人伤心)。
+
+Using an app like
+[Terragen](https://planetside.co.uk),
+you can render photo-realistic 3D landscapes,
+with fine-tuned control over the earth, sun, and sky.
+
+可以选择用 [Terragen](https://planetside.co.uk/) 这类应用,它打造了一个逼真的 3D 世界,还能对太阳、地球、天空进行微调。
+
+You can make it even easier for yourself by
+downloading an elevation map from the U.S. Geological Survey's
+[National Map website](https://viewer.nationalmap.gov/basic/)
+and using that as a template for your 3D rendering project.
+
+想要更加简化,还可以从美国地质调查局的[国家地图网站](https://viewer.nationalmap.gov/basic/)上下载高程地图,以用于 3D 渲染的模板。
+
+### Downloading Pre-Made Dynamic Desktops
+
+### 下载预制的 Dynamic Desktops
+
+Or if you have actual work to do
+and can't be bothered to spend your time making pretty pictures,
+you can always just pay someone else to do it for you.
+
+再或者,你每天都非常多的工作要做,抽不出时间捣腾好看的图片,也可以选择付费从别人那里购买。
+
+We're personally fans of the the
+[24 Hour Wallpaper](https://www.jetsoncreative.com/24hourwallpaper/) app.
+If you have any other recommendations,
+[@ us on Twitter!](https://twitter.com/NSHipster/).
+
+我个人是 [24 Hour Wallpaper](https://www.jetsoncreative.com/24hourwallpaper) 这款应用的粉丝。如果你有别的推荐,欢迎[联系我们](https://twitter.com/NSHipster/)。
\ No newline at end of file