在操场上拍摄现场照片

时间:2023-01-23 18:58:56

I've done a fair amount of searching the web, but I'm currently attempting to work with "Live Photos" in Playground. I'm aware of the framework (PHLivePhoto), I just have no clue if working with them in Playground is possible due to that fact that there's not much to "import" as there doesn't seem to be any "Live Photos" available for download online. Any ideas?

我在网上搜索了很多次,但目前我正尝试在操场上拍摄“现场照片”。我知道这个框架(PHLivePhoto),我不知道是否可以在操场上使用它们,因为没有太多的“导入”,因为似乎没有任何“实时照片”可以在线下载。什么好主意吗?

1 个解决方案

#1


22  

It's possible to make and view a PHLivePhoto in the Playground from the elements of an actual Live Photo.

在操场上,你可以根据现场照片的元素制作和观看PHLivePhoto。

In OS X's Photos app, select a Live Photo and go to menu

在OS X的照片应用程序中,选择一个实时照片并进入菜单

File > Export > Export original...

文件>导出>原件…

在操场上拍摄现场照片

It will create a .JPG and a .mov.

它将创建. jpg和.mov。

Drop these two files in the Resources folder of the Playground (menu View > Navigators > Show Project Navigator).

将这两个文件放到游乐场的资源文件夹中(菜单视图>导航器>显示项目导航器)。

Get the URLs for these two files with NSBundle (in my example the files are "IMG_0001.JPG" and "IMG_0001.mov"):

使用NSBundle获取这两个文件的url(在我的示例中,这些文件是“IMG_0001”)。JPG”和“IMG_0001.mov”):

let imgURL = NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "JPG")!
let movURL = NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "mov")!

And create an actual image, we will need it for the Live Photo preview image:

并创建一个实际的图像,我们将需要它为实时照片预览图像:

let prevImg = UIImage(named: "IMG_0001.JPG")!

Import the necessary frameworks:

进口所需的框架:

import Photos
import PhotosUI
import XCPlayground

And set the Playground in asynchronous mode:

并以异步模式设置游乐场:

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

Now we're going to use PHLivePhoto's requestLivePhotoWithResourceFileURLs method to create a PHLivePhoto from our elements:

现在我们将使用PHLivePhoto的requestLivePhotoWithResourceFileURLs方法从我们的元素中创建一个PHLivePhoto:

func makeLivePhotoFromItems(imageURL: NSURL, videoURL: NSURL, previewImage: UIImage, completion: (livePhoto: PHLivePhoto) -> Void) {
    PHLivePhoto.requestLivePhotoWithResourceFileURLs([imageURL, videoURL], placeholderImage: previewImage, targetSize: CGSizeZero, contentMode: PHImageContentMode.AspectFit) {
        (livePhoto, infoDict) -> Void in
        // for debugging: print(infoDict)
        if let lp = livePhoto {
            completion(livePhoto: lp)
        }
    }
}

Then we call like this:

然后我们这样称呼:

makeLivePhotoFromItems(imgURL, videoURL: movURL, previewImage: prevImg) { (livePhoto) -> Void in
    // "livePhoto" is your PHLivePhoto object
}

For example, let's say you want the Playground to make a live view:

例如,假设你想让操场变成一个活生生的场景:

makeLivePhotoFromItems(imgURL, videoURL: movURL, previewImage: prevImg) { (livePhoto) -> Void in
    let rect = CGRect(x: 0, y: 0, width: 2048, height: 1536)
    let livePhotoView = PHLivePhotoView(frame: rect)
    livePhotoView.livePhoto = livePhoto
    XCPlaygroundPage.currentPage.liveView = livePhotoView
    livePhotoView.startPlaybackWithStyle(PHLivePhotoViewPlaybackStyle.Full)
}

Note that since there's no way to interact with the live view to start the playback of the Live Photo we have to do it ourselves with PHLivePhotoView's startPlaybackWithStyle method.

注意,由于无法与live视图交互来启动live照片的回放,所以我们必须自己使用PHLivePhotoView的startPlaybackWithStyle方法。

You can force the live view to appear in the Playground by showing the Assistant Editor in menu

您可以通过在菜单中显示助理编辑器来强制实时视图出现在操场上。

View > Assistant Editor > Show Assistant Editor

查看>助理编辑>显示助理编辑

在操场上拍摄现场照片

Note: it can take some time for the Playground to create the PHLivePhoto and initiate the live view.

注意:创建PHLivePhoto并启动live view需要一些时间。


With Xcode 7.3b+ we can finally have some UI interaction in Playgrounds.

有了Xcode 7.3b+,我们终于可以在操场上进行一些UI交互了。

I've made an adaptation of this answer with a simple view and touchesBegan, just click the LivePhoto when the console says so:

我对这个答案进行了修改,使用了一个简单的视图和touchesBegan,点击LivePhoto,控制台显示:

import UIKit
import XCPlayground

import Photos
import PhotosUI

class PLView: UIView {

    let image: UIImage
    let imageURL: NSURL
    let videoURL: NSURL

    let liveView: PHLivePhotoView

    init(image: UIImage, imageURL: NSURL, videoURL: NSURL) {
        self.image = image
        self.imageURL = imageURL
        self.videoURL = videoURL
        let rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
        self.liveView = PHLivePhotoView(frame: rect)
        super.init(frame: rect)
        self.addSubview(self.liveView)
    }

    func prepareLivePhoto() {
        makeLivePhotoFromItems { (livePhoto) in
            self.liveView.livePhoto = livePhoto
            print("\nReady! Click on the LivePhoto in the Assistant Editor panel!\n")
        }
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        print("\nClicked! Wait for it...\n")
        self.liveView.startPlaybackWithStyle(.Full)
    }

    private func makeLivePhotoFromItems(completion: (PHLivePhoto) -> Void) {
        PHLivePhoto.requestLivePhotoWithResourceFileURLs([imageURL, videoURL], placeholderImage: image, targetSize: CGSizeZero, contentMode: .AspectFit) {
            (livePhoto, infoDict) -> Void in
            // This "canceled" condition is just to avoid redundant passes in the Playground preview panel.
            if let canceled = infoDict[PHLivePhotoInfoCancelledKey] as? Int where canceled == 0 {
                if let livePhoto = livePhoto {
                    completion(livePhoto)
                }
            }
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}



XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

let plview = PLView(image: UIImage(named: "IMG_0001.JPG")!,
                 imageURL: NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "JPG")!,
                 videoURL: NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "mov")!)

XCPlaygroundPage.currentPage.liveView = plview

plview.prepareLivePhoto()

The same example for Swift 3.0.2 (Xcode 8.2.1):

Swift 3.0.2的相同示例(Xcode 8.2.1):

import UIKit
import PlaygroundSupport
import Photos
import PhotosUI

class PLView: UIView {

    let image: UIImage
    let imageURL: URL
    let videoURL: URL

    let liveView: PHLivePhotoView

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    init(image: UIImage, imageURL: URL, videoURL: URL) {
        self.image = image
        self.imageURL = imageURL
        self.videoURL = videoURL
        let rect = CGRect(x: 0, y: 0, width: 300, height: 400)
        self.liveView = PHLivePhotoView(frame: rect)
        super.init(frame: rect)
        self.addSubview(self.liveView)
    }

    func prepareLivePhoto() {
        makeLivePhotoFromItems { (livePhoto) in
            self.liveView.livePhoto = livePhoto
            print("\nReady! Click on the LivePhoto in the Assistant Editor panel!\n")
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("\nClicked! Wait for it...\n")
        self.liveView.startPlayback(with: .full)
    }

    private func makeLivePhotoFromItems(completion: @escaping (PHLivePhoto) -> Void) {
        PHLivePhoto.request(withResourceFileURLs: [imageURL, videoURL], placeholderImage: image, targetSize: CGSize.zero, contentMode: .aspectFit) {
            (livePhoto, infoDict) -> Void in

            if let canceled = infoDict[PHLivePhotoInfoCancelledKey] as? NSNumber,
                canceled == 0,
                let livePhoto = livePhoto
            {
                completion(livePhoto)
            }
        }
    }

}

let plview = PLView(image: UIImage(named: "IMG_0001.JPG")!,
                    imageURL: Bundle.main.url(forResource: "IMG_0001", withExtension: "JPG")!,
                    videoURL: Bundle.main.url(forResource: "IMG_0001", withExtension: "mov")!)

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = plview

plview.prepareLivePhoto()

#1


22  

It's possible to make and view a PHLivePhoto in the Playground from the elements of an actual Live Photo.

在操场上,你可以根据现场照片的元素制作和观看PHLivePhoto。

In OS X's Photos app, select a Live Photo and go to menu

在OS X的照片应用程序中,选择一个实时照片并进入菜单

File > Export > Export original...

文件>导出>原件…

在操场上拍摄现场照片

It will create a .JPG and a .mov.

它将创建. jpg和.mov。

Drop these two files in the Resources folder of the Playground (menu View > Navigators > Show Project Navigator).

将这两个文件放到游乐场的资源文件夹中(菜单视图>导航器>显示项目导航器)。

Get the URLs for these two files with NSBundle (in my example the files are "IMG_0001.JPG" and "IMG_0001.mov"):

使用NSBundle获取这两个文件的url(在我的示例中,这些文件是“IMG_0001”)。JPG”和“IMG_0001.mov”):

let imgURL = NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "JPG")!
let movURL = NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "mov")!

And create an actual image, we will need it for the Live Photo preview image:

并创建一个实际的图像,我们将需要它为实时照片预览图像:

let prevImg = UIImage(named: "IMG_0001.JPG")!

Import the necessary frameworks:

进口所需的框架:

import Photos
import PhotosUI
import XCPlayground

And set the Playground in asynchronous mode:

并以异步模式设置游乐场:

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

Now we're going to use PHLivePhoto's requestLivePhotoWithResourceFileURLs method to create a PHLivePhoto from our elements:

现在我们将使用PHLivePhoto的requestLivePhotoWithResourceFileURLs方法从我们的元素中创建一个PHLivePhoto:

func makeLivePhotoFromItems(imageURL: NSURL, videoURL: NSURL, previewImage: UIImage, completion: (livePhoto: PHLivePhoto) -> Void) {
    PHLivePhoto.requestLivePhotoWithResourceFileURLs([imageURL, videoURL], placeholderImage: previewImage, targetSize: CGSizeZero, contentMode: PHImageContentMode.AspectFit) {
        (livePhoto, infoDict) -> Void in
        // for debugging: print(infoDict)
        if let lp = livePhoto {
            completion(livePhoto: lp)
        }
    }
}

Then we call like this:

然后我们这样称呼:

makeLivePhotoFromItems(imgURL, videoURL: movURL, previewImage: prevImg) { (livePhoto) -> Void in
    // "livePhoto" is your PHLivePhoto object
}

For example, let's say you want the Playground to make a live view:

例如,假设你想让操场变成一个活生生的场景:

makeLivePhotoFromItems(imgURL, videoURL: movURL, previewImage: prevImg) { (livePhoto) -> Void in
    let rect = CGRect(x: 0, y: 0, width: 2048, height: 1536)
    let livePhotoView = PHLivePhotoView(frame: rect)
    livePhotoView.livePhoto = livePhoto
    XCPlaygroundPage.currentPage.liveView = livePhotoView
    livePhotoView.startPlaybackWithStyle(PHLivePhotoViewPlaybackStyle.Full)
}

Note that since there's no way to interact with the live view to start the playback of the Live Photo we have to do it ourselves with PHLivePhotoView's startPlaybackWithStyle method.

注意,由于无法与live视图交互来启动live照片的回放,所以我们必须自己使用PHLivePhotoView的startPlaybackWithStyle方法。

You can force the live view to appear in the Playground by showing the Assistant Editor in menu

您可以通过在菜单中显示助理编辑器来强制实时视图出现在操场上。

View > Assistant Editor > Show Assistant Editor

查看>助理编辑>显示助理编辑

在操场上拍摄现场照片

Note: it can take some time for the Playground to create the PHLivePhoto and initiate the live view.

注意:创建PHLivePhoto并启动live view需要一些时间。


With Xcode 7.3b+ we can finally have some UI interaction in Playgrounds.

有了Xcode 7.3b+,我们终于可以在操场上进行一些UI交互了。

I've made an adaptation of this answer with a simple view and touchesBegan, just click the LivePhoto when the console says so:

我对这个答案进行了修改,使用了一个简单的视图和touchesBegan,点击LivePhoto,控制台显示:

import UIKit
import XCPlayground

import Photos
import PhotosUI

class PLView: UIView {

    let image: UIImage
    let imageURL: NSURL
    let videoURL: NSURL

    let liveView: PHLivePhotoView

    init(image: UIImage, imageURL: NSURL, videoURL: NSURL) {
        self.image = image
        self.imageURL = imageURL
        self.videoURL = videoURL
        let rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
        self.liveView = PHLivePhotoView(frame: rect)
        super.init(frame: rect)
        self.addSubview(self.liveView)
    }

    func prepareLivePhoto() {
        makeLivePhotoFromItems { (livePhoto) in
            self.liveView.livePhoto = livePhoto
            print("\nReady! Click on the LivePhoto in the Assistant Editor panel!\n")
        }
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        print("\nClicked! Wait for it...\n")
        self.liveView.startPlaybackWithStyle(.Full)
    }

    private func makeLivePhotoFromItems(completion: (PHLivePhoto) -> Void) {
        PHLivePhoto.requestLivePhotoWithResourceFileURLs([imageURL, videoURL], placeholderImage: image, targetSize: CGSizeZero, contentMode: .AspectFit) {
            (livePhoto, infoDict) -> Void in
            // This "canceled" condition is just to avoid redundant passes in the Playground preview panel.
            if let canceled = infoDict[PHLivePhotoInfoCancelledKey] as? Int where canceled == 0 {
                if let livePhoto = livePhoto {
                    completion(livePhoto)
                }
            }
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}



XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

let plview = PLView(image: UIImage(named: "IMG_0001.JPG")!,
                 imageURL: NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "JPG")!,
                 videoURL: NSBundle.mainBundle().URLForResource("IMG_0001", withExtension: "mov")!)

XCPlaygroundPage.currentPage.liveView = plview

plview.prepareLivePhoto()

The same example for Swift 3.0.2 (Xcode 8.2.1):

Swift 3.0.2的相同示例(Xcode 8.2.1):

import UIKit
import PlaygroundSupport
import Photos
import PhotosUI

class PLView: UIView {

    let image: UIImage
    let imageURL: URL
    let videoURL: URL

    let liveView: PHLivePhotoView

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    init(image: UIImage, imageURL: URL, videoURL: URL) {
        self.image = image
        self.imageURL = imageURL
        self.videoURL = videoURL
        let rect = CGRect(x: 0, y: 0, width: 300, height: 400)
        self.liveView = PHLivePhotoView(frame: rect)
        super.init(frame: rect)
        self.addSubview(self.liveView)
    }

    func prepareLivePhoto() {
        makeLivePhotoFromItems { (livePhoto) in
            self.liveView.livePhoto = livePhoto
            print("\nReady! Click on the LivePhoto in the Assistant Editor panel!\n")
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("\nClicked! Wait for it...\n")
        self.liveView.startPlayback(with: .full)
    }

    private func makeLivePhotoFromItems(completion: @escaping (PHLivePhoto) -> Void) {
        PHLivePhoto.request(withResourceFileURLs: [imageURL, videoURL], placeholderImage: image, targetSize: CGSize.zero, contentMode: .aspectFit) {
            (livePhoto, infoDict) -> Void in

            if let canceled = infoDict[PHLivePhotoInfoCancelledKey] as? NSNumber,
                canceled == 0,
                let livePhoto = livePhoto
            {
                completion(livePhoto)
            }
        }
    }

}

let plview = PLView(image: UIImage(named: "IMG_0001.JPG")!,
                    imageURL: Bundle.main.url(forResource: "IMG_0001", withExtension: "JPG")!,
                    videoURL: Bundle.main.url(forResource: "IMG_0001", withExtension: "mov")!)

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = plview

plview.prepareLivePhoto()