Swift 自定義圖片選擇器(二) -- 獲取圖片資源

上一篇簡單的介紹了一下Photos,下面就開始介紹demo里面的業務類。

相冊列表項

表示一個非空的相冊,即非空的PHAsset資源的集合。主要用于顯示圖片列表,并且在選中某一列表時,顯示該相冊里面的圖片資源。

  /// 相簿列表項
  struct AlbumItem {
  var title : String?     // 相冊的標題
  var fetchResult : PHFetchResult<PHAsset>    // 資源集合

  init(title: String?, fetchResult: PHFetchResult<PHAsset>) {
    self.title = title
    self.fetchResult = fetchResult
}
}

重載運算符 +

AlbumItem 是自定義的數據類型,為了實現該類型的數組相加,需要重載運算符,然后就可以像其他數據類型一樣直接使用符號 “+” 來合并兩個數組。(重載運算符需要在全局域中,就是跟AlbumItem在同一層級下)

postfix operator +

func + (left: [AlbumItem]?, right: [AlbumItem]?) ->[AlbumItem]? {
if (left == nil) {
    return right
}

if (right == nil) {
    return left
}
var result = left!

for (_, item) in right!.enumerated() {
    result.append(item)
}

return result
}

PickerHelper 圖片資源獲取幫助類

所有的關于圖片資源獲取的方法都封裝在PickerHelper里面,并且使用單例設計模式,設置成單例類。

/// 獲取圖片的資源的類
class PickerHelper: NSObject {
static let helperDefault : PickerHelper = {
    let helper = PickerHelper()
    return helper
}()

var targetSize = CGSize(width: 320, height: 675)    // 默認大圖的大小
var maxCount = 9    // 默認最多可選9張圖片
}

targetSize 和maxCount 公開可變,是讓用戶可以根據需要進行修改。

獲取相冊數組

/// 獲取智能相冊
///
/// - returns: 智能相冊數組 PHFetchResult<PHAsset>
func getSmartAlbums() -> [AlbumItem]? {
    //獲取所有的智能相冊
    let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
    // 獲取資源選項設置,以創建時間升序排序
    let options = PHFetchOptions()
    options.sortDescriptors = [NSSortDescriptor.init(key: "creationDate", ascending: true)]
    let albumsArray = getAssetResultInCollection(smartAlbums, fetchOptions: options)
    
    return albumsArray
}

/// 從PHAssetCollection中獲取相冊,主要是用于相冊列表
///
/// - parameter collection: 相冊集合
/// - parameter options:    獲取相冊的相關設置參數
///
/// - returns: 相冊數組
private func getAssetResultInCollection(_ collection: PHFetchResult<PHAssetCollection>, fetchOptions options: PHFetchOptions) ->[AlbumItem]? {
    var albumsArray = [AlbumItem]()
    
    for index in 0..<collection.count {
        //獲取一個相冊
        let assetCollection = collection[index];
        
        //然后從每一個智能相冊中獲取資源,獲取到的是一個list
        let assetFecthResults = PHAsset.fetchAssets(in: assetCollection, options: nil);
        print("\(assetCollection.localizedTitle!)相冊,共有照片數:\(assetFecthResults.count)")
        
        if assetFecthResults.count > 0 {
            //有照片的相冊
            let album = AlbumItem.init(title: assetCollection.localizedTitle, fetchResult: assetFecthResults)
            
            albumsArray.append(album)
        }
    }
    
    return albumsArray
}

獲取用戶創建的相冊數組

/// 獲取用戶創建的相冊
///
/// - returns: 相冊數組
func getUserAlbums() -> [AlbumItem]? {
    let userAlbums = PHCollectionList.fetchTopLevelUserCollections(with: nil) as! PHFetchResult<PHAssetCollection>
    let options = PHFetchOptions()
    options.sortDescriptors = [NSSortDescriptor.init(key: "creationDate", ascending: true)]
    
    let albumsArray = getAssetResultInCollection(userAlbums, fetchOptions: options)
    
    return albumsArray
}

PictureItem

表示一個圖片資源,并且保存了獲取到的大圖、小圖和該資源是否被選中

class PictureItem: NSObject {
/// 圖片資源
var asset = PHAsset()
/// 顯示的小圖
var lowImage: UIImage?
/// 上傳的大圖
var hightImage: UIImage?
/// 是否選中的標志
var isSelected = false

init(asset: PHAsset, lowImage: UIImage?, hightImage: UIImage?, isSelected: Bool = false) {
    self.asset = asset
    self.lowImage = lowImage
    self.hightImage = hightImage
    self.isSelected = isSelected
}
}

獲取相冊的圖片

/// 獲取某個相冊里面的圖片資源
///
/// - parameter albumItem: 相冊
///
/// - returns: 圖片數組 [PictureItem]
func getPicturesInAlbumItem(_ albumItem: AlbumItem) -> [PictureItem] {
    var pictures = [PictureItem]()
    
    albumItem.fetchResult.enumerateObjects({ (asset, curIndex, nil) in
        pictures.append(PictureItem.init(asset: asset, lowImage: nil, hightImage: nil))
    })
    
    return pictures
}

/// 從圖片資源PHAsset中獲取指定大小的image對象
///
/// - parameter asset:           Asset圖片資源
/// - parameter targetSize:      指定尺寸
/// - parameter finishedCallack: 獲取后返回的block
func getImageWithAsset(_ asset: PHAsset, size targetSize: CGSize, finishedCallack: @escaping (_ image: UIImage) -> ()) {
    let options = PHImageRequestOptions()
    options.resizeMode = .exact // 返回圖像與目標size保持一致
    options.deliveryMode = .highQualityFormat   // 只返回高像素的圖像
    var size = targetSize
    
    // 如果沒有目標大小,則返回原圖
    if targetSize == .zero {
        size = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
    }
    
    PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .default, options: options) { (image, info) in
        // 如果是image是nil 則直接返回
        guard let image = image else {
            return
        }
        
        // 拿到圖片,則返回
        finishedCallack(image)
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,533評論 1 51
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,076評論 25 708
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • 素蓮寫盡春顏色, 桃李芳菲淺草蒙。 詩酒琴棋閑富貴, 卷簾邀月看云生。
    淡淡青蓮閱讀 545評論 8 10
  • 上學是為了工作,努力工作是為了升職加薪,交朋友是為了人脈,談戀愛是為了結婚,買房子是為了升值,生孩子是為了防老,旅...
    那個人_村里椿樹閱讀 298評論 0 2