SilenceLove / HXPhotoPicker

图片/视频选择器 - 支持LivePhoto、GIF图片选择、3DTouch预览、在线下载iCloud上的资源、编辑图片/视频、浏览网络图片 功能 Imitation wx photo/image picker - support for LivePhoto, GIF image selection, 3DTouch preview, Download the resources on iCloud online, browse the web image function
https://github.com/SilenceLove/HXPhotoPicker
MIT License
2.99k stars 635 forks source link
3d-touch browser editor gif icloud image imagepicker ios livephoto photo photoeditor photokit photopicker phpicker picker previewimage swift uiimagepickercontroller videoeditor

中文 | English

一款图片/视频选择器-支持LivePhoto、GIF选择、iCloud/网络资源在线下载、图片/视频编辑

目录

功能

要求

安装

Swift Package Manager

⚠️ 需要 Xcode 12.0 及以上版本来支持资源文件/本地化文件的添加。

dependencies: [
    .package(url: "https://github.com/SilenceLove/HXPhotoPicker.git", .upToNextMajor(from: "4.2.1"))
]

CocoaPods

将下面内容添加到 Podfile,并执行依赖更新。


iOS 12.0+
pod 'HXPhotoPicker'

/// 不包含 Kingfisher,相机不包含定位功能
pod `HXPhotoPicker/Lite`

/// 相机不包含定位功能
pod `HXPhotoPicker/NoLocation`

/// 只有选择器
pod `HXPhotoPicker/Picker`
pod `HXPhotoPicker/Picker/Lite`

/// 只有编辑器
pod `HXPhotoPicker/Editor`
pod `HXPhotoPicker/Editor/Lite`

/// 只有相机
pod `HXPhotoPicker/Camera`
/// 不包含定位功能
pod `HXPhotoPicker/Camera/Lite`

iOS 10.0+
pod 'HXPhotoPicker-Lite'
pod 'HXPhotoPicker-Lite/Picker'
pod 'HXPhotoPicker-Lite/Editor'
pod 'HXPhotoPicker-Lite/Camera'

v4.0以下的ObjC版本
pod 'HXPhotoPickerObjC'

准备工作

按需在你的 Info.plist 中添加以下键值:

Key 模块 备注
NSPhotoLibraryUsageDescription Picker 允许访问相册
NSPhotoLibraryAddUsageDescription Picker 允许保存图片至相册
PHPhotoLibraryPreventAutomaticLimitedAccessAlert Picker 设置为 YES iOS 14+ 以禁用自动弹出添加更多照片的弹框(Picker 已适配 Limited 功能,可由用户主动触发,提升用户体验)
NSCameraUsageDescription Camera 允许使用相机
NSMicrophoneUsageDescription Camera 允许使用麦克风

快速上手

import HXPhotoPicker

class ViewController: UIViewController {

    func presentPickerController() {
        // 设置与微信主题一致的配置
        let config = PickerConfiguration.default

        // 方法一:async/await
        // 使用`Photo`
        let images: [UIImage] = try await Photo.picker(config)
        let urls: [URL] = try await Photo.picker(config)
        let urlResult: [AssetURLResult] = try await Photo.picker(config)
        let assetResult: [AssetResult] = try await Photo.picker(config)
        // 使用`PhotoPickerController`
        let images: [UIImage] = try await PhotoPickerController.picker(config)
        let urls: [URL] = try await PhotoPickerController.picker(config)
        let urlResult: [AssetURLResult] = try await PhotoPickerController.picker(config)
        let assetResult: [AssetResult] = try await PhotoPickerController.picker(config)

        let pickerResult = try await Photo.picker(config)
        let images: [UIImage] = try await pickerResult.objects()
        let urls: [URL] = try await pickerResult.objects()
        let urlResults: [AssetURLResult] = try await pickerResult.objects()
        let assetResults: [AssetResult] = try await pickerResult.objects()

        // 方法二:
        let pickerController = PhotoPickerController(picker: config)
        pickerController.pickerDelegate = self
        // 当前被选择的资源对应的 PhotoAsset 对象数组
        pickerController.selectedAssetArray = selectedAssets 
        // 是否选中原图
        pickerController.isOriginal = isOriginal
        present(pickerController, animated: true, completion: nil)

        // 方法三:
        Photo.picker(
            config
        ) { result, pickerController in
            // 选择完成的回调
            // result 选择结果
            //  .photoAssets 当前选择的数据
            //  .isOriginal 是否选中了原图
            // photoPickerController 对应的照片选择控制器
        } cancel: { pickerController in
            // 取消的回调
            // photoPickerController 对应的照片选择控制器 
        }
    }
}

extension ViewController: PhotoPickerControllerDelegate {

    /// 选择完成之后调用
    /// - Parameters:
    ///   - pickerController: 对应的 PhotoPickerController
    ///   - result: 选择的结果
    ///     result.photoAssets  选择的资源数组
    ///     result.isOriginal   是否选中原图
    func pickerController(
        _ pickerController: PhotoPickerController, 
        didFinishSelection result: PickerResult
    ) {
        // async/await
        let images: [UIImage] = try await result.objects()
        let urls: [URL] = try await result.objects()
        let urlResults: [AssetURLResult] = try await result.objects()
        let assetResults: [AssetResult] = try await result.objects()

        result.getImage { (image, photoAsset, index) in
            if let image = image {
                print("success", image)
            }else {
                print("failed")
            }
        } completionHandler: { (images) in
            print(images)
        }
    }

    /// 点击取消时调用
    /// - Parameter pickerController: 对应的 PhotoPickerController
    func pickerController(didCancel pickerController: PhotoPickerController) {

    }
}

如何获取

获取 UIImage

/// 如果为视频的话获取则是视频封面
// async/await
// compression: 压缩参数,不传则不压缩 
let image: UIImage = try await photoAsset.object(compression)

/// 获取指定`Size`的`UIImage`
/// targetSize: 指定imageSize
/// targetMode: 裁剪模式
let image = try await photoAsset.image(targetSize: .init(width: 200, height: 200), targetMode: .fill)

// compressionQuality: 压缩参数,不传则不压缩 
photoAsset.getImage(compressionQuality: compressionQuality) { image in
    print(image)
}

获取 URL

// async/await 
// compression: 压缩参数,不传则不压缩 
let url: URL = try await photoAsset.object(compression)
let urlResult: AssetURLResult = try await photoAsset.object(compression)

// compression: 压缩参数,不传则不压缩
photoAsset.getURL(compression: compression) { result in
    switch result {
    case .success(let urlResult):
        // 媒体类型
        switch urlResult.mediaType {
        case .photo:
            // 图片
        case .video:
            // 视频
        }

        // url类型
        switch urlResult.urlType {
        case .local:
            // 本地URL
        case .network:
            // 网络URL
        }

        // 获取的地址
        print(urlResult.url)

        // LivePhoto 里面包含的 图片和视频 url
        print(urlResult.livePhoto) 

    case .failure(let error):
        print(error)
    }
}

获取其他

/// 获取缩略图
let thumImage = try await photoAsset.requesThumbnailImage()

/// 获取预览图
let previewImage = try await photoAsset.requestPreviewImage()

/// 获取 AVAsset
let avAsset = try await photoAsset.requestAVAsset()

/// 获取 AVPlayerItem
let playerItem = try await photoAsset.requestPlayerItem()

/// 获取 PHLivePhoto
let livePhoto = try await photoAsset.requestLivePhoto()

更新日志

最近更新 | 版本 | 发布时间 | Xcode | Swift | iOS | | ---- | ---- | ---- | ---- | ---- | | [v4.2.1](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#421) | 2024-05-18 | 15.0.0 | 5.9.0 | 12.0+ |
历史记录 | 版本 | 发布时间 | Xcode | Swift | iOS | | ---- | ---- | ---- | ---- | ---- | | [v4.2.0](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#420) | 2024-04-23 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.9](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#419) | 2024-04-09 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.8](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#418) | 2024-03-24 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.7](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#417) | 2024-03-09 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.6](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#416) | 2024-02-16 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.5](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#415) | 2024-01-10 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.4](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#414) | 2023-12-24 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.3](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#413) | 2023-12-16 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.2](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#412) | 2023-12-02 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.1](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#411) | 2023-11-14 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.1.0](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#410) | 2023-11-07 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.0.9](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#409) | 2023-10-22 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.0.8](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#408) | 2023-10-13 | 15.0.0 | 5.9.0 | 12.0+ | | [v4.0.7](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#407) | 2023-09-23 | 14.3.0 | 5.7.0 | 12.0+ | | [v4.0.6](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#406) | 2023-09-09 | 14.3.0 | 5.7.0 | 12.0+ | | [v4.0.5](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#405) | 2023-08-12 | 14.3.0 | 5.7.0 | 12.0+ | | [v4.0.4](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#404) | 2023-07-30 | 14.3.0 | 5.7.0 | 12.0+ | | [v4.0.3](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#403) | 2023-07-06 | 14.3.0 | 5.7.0 | 12.0+ | | [v4.0.2](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#402) | 2023-06-24 | 14.3.0 | 5.7.0 | 12.0+ | | [v4.0.1](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#401) | 2023-06-17 | 14.3.0 | 5.7.0 | 12.0+ | | [v4.0.0](https://github.com/SilenceLove/HXPhotoPicker/blob/master/Documentation/RELEASE_NOTE_CN.md#400) | 2023-06-15 | 14.3.0 | 5.7.0 | 12.0+ | | [v3.0.0](https://github.com/SilenceLove/HXPhotoPickerObjC#-%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95---update-history) | 2022-09-18 | 14.0.0 | ----- | 8.0+ |

演示效果

选择照片 图片编辑 视频编辑
IMAGE ALT TEXT IMAGE ALT TEXT IMAGE ALT TEXT

界面展示

版权协议

HXPhotoPicker 基于 MIT 协议进行分发和使用,更多信息参见协议文件

支持❤️

Buy Me A Coffee

Stargazers over time

🔝回到顶部