如何在Swift中从相机或照片库加载图像

4

如何使用相机拍照或从照片库中选择图像,并能够在imageView中显示它?

如果有任何帮助,将不胜感激。


我为你发布了一个答案,但是你得到了所有的踩因为这不是“为你编写代码”的网站。你必须提供代码,我们帮助你找错误并改进你的代码。所以下一次尝试通过Google解决方案并在卡住时寻求帮助。现在:我已经完全为你发布了一个有效的选项。玩得开心。 - David Seek
1
我明白这不是让别人替我完成工作的地方,我只是想知道从哪里开始。我并不指望有人为我写出来,但我很感激你发表的答案。 - Dimitre Bogdanov
1
我并不想冒犯你,伙计。只是想告诉你为什么你收到了这么多的踩。我已经给了你一个赞,所以情况不会太糟。如果我的工作对你有帮助,我很高兴回答你的问题,让你能够检查它。如果你需要进一步的帮助,随时让我知道。 - David Seek
1个回答

24

完整更新Swift 5+,包括Github Repo

首先,我们想将所有内容组织到一个专用类中。

import MobileCoreServices
import UIKit

class CameraProvider: NSObject {

    enum PhotoLibraryTypes {
        case photoLibrary, savedPhotosAlbum
        var casted: UIImagePickerController.SourceType {
            switch self {
            case .photoLibrary: return UIImagePickerController.SourceType.photoLibrary
            case .savedPhotosAlbum: return UIImagePickerController.SourceType.savedPhotosAlbum
            }
        }
    }

    public typealias SourceType = UIImagePickerController.SourceType
    public typealias ImagePicker = UIImagePickerController
    public typealias Delegate = UINavigationControllerDelegate & UIImagePickerControllerDelegate

    private let delegate: Delegate

    init(delegate: Delegate) {
        self.delegate = delegate
    }

    // MARK: - Public

    public func getImagePicker(source: PhotoLibraryTypes,
                               canEditPhotos: Bool = true,
                               onlyImages: Bool = false) throws -> ImagePicker {

        do {
            return try getBaseController(
                source: source.casted,
                allowsEditing: canEditPhotos,
                onlyImages: onlyImages
            )
        } catch {
            throw error
        }
    }

    public func getCamera(canEditPhotos: Bool = true,
                          onlyImages: Bool = false) throws -> ImagePicker {

        do {
            let picker = try getBaseController(
                source: .camera,
                allowsEditing: canEditPhotos,
                onlyImages: onlyImages
            )

            if UIImagePickerController.isCameraDeviceAvailable(.rear) {
                picker.cameraDevice = .rear
            } else if UIImagePickerController.isCameraDeviceAvailable(.front) {
                picker.cameraDevice = .front
            } else {
                throw "No known camera type available"
            }

            picker.showsCameraControls = true
            return picker
        } catch {
            throw error
        }
    }

    // MARK: - Private

    private func getBaseController(source: SourceType,
                                   allowsEditing: Bool,
                                   onlyImages: Bool) throws -> ImagePicker {

        guard UIImagePickerController.isSourceTypeAvailable(source) else {
            throw "Requested source not available"
        }

        let picker = UIImagePickerController()
        let imageType = kUTTypeImage as String
        picker.sourceType = source
        picker.allowsEditing = allowsEditing
        picker.delegate = self.delegate

        if onlyImages,
           let mediaTypes = UIImagePickerController.availableMediaTypes(for: source),
           mediaTypes.contains(imageType){
            picker.mediaTypes = [imageType]
        }

        return picker
    }
}

extension String: LocalizedError {
    public var errorDescription: String? { return self }
}

最后,我们按以下方式调用 CameraProvider

import UIKit

class ViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let provider = CameraProvider(delegate: self)

        do {
            let picker = try provider.getImagePicker(source: .photoLibrary)
            present(picker, animated: true)
        } catch {
            NSLog("Error: \(error.localizedDescription)")
        }
    }
}

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let image = (
            info[UIImagePickerController.InfoKey.editedImage] as? UIImage ??
            info[UIImagePickerController.InfoKey.originalImage] as? UIImage
        )
        picker.dismiss(animated: true, completion: nil)
    }
}

2
很好的答案,David感谢你分享。 - Drew
你的代码运行得很好,除了从canEdit: false的库中加载时,当我选择一张图片时它会崩溃。 - Pedro Cavaleiro
还可以参考这个简单的方法,它支持Swift 3:https://dev59.com/W1gR5IYBdhLWcg3wHqTB#41717882 - anas.p
1
非常有用的答案。谢谢你。但我想有一个小错误。您在getPhotoLibraryOn中检查了isPhotoLibraryAvailable两次。第二个应该是isSavedPhotoAlbumAvailable。 - AtaerCaner
2
太棒了!完美地运作了。谢谢你。 - Mo Zaatar
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接