2016-01-21 54 views
0

我試圖從PHAsset的用戶相機膠捲中檢索超過1,000張圖像,但如果它只是縮略圖,它最終會崩潰或需要很長時間。這裏是我的功能,我檢索圖像...使用PHAsset檢索多個圖像

func retrieveImages(thumbnail: Bool) { 

    /* Retrieve the items in order of modification date, ascending */ 
    let options = PHFetchOptions() 
    options.sortDescriptors = [NSSortDescriptor(key: "modificationDate", 
     ascending: false)] 

    /* Then get an object of type PHFetchResult that will contain 
    all our image assets */ 
    let assetResults = PHAsset.fetchAssetsWithMediaType(.Image, 
     options: options) 

    let imageManager = PHCachingImageManager() 

    assetResults.enumerateObjectsUsingBlock{(object: AnyObject!, 
     count: Int, 
     stop: UnsafeMutablePointer<ObjCBool>) in 


     if object is PHAsset{ 
      let asset = object as! PHAsset 
      print("Inside If object is PHAsset, This is number 1") 

      var imageSize: CGSize! 

      if thumbnail == true { 
       imageSize = CGSize(width: 100, height: 100) 

      } else { 
       imageSize = CGSize(width: self.cameraView.bounds.width, height: self.cameraView.bounds.height) 

      } 
      /* For faster performance, and maybe degraded image */ 
      let options = PHImageRequestOptions() 
      options.deliveryMode = .FastFormat 
      options.synchronous = true 

      imageManager.requestImageForAsset(asset, 
       targetSize: imageSize, 
       contentMode: .AspectFill, 
       options: options, 
       resultHandler: { (image, _: [NSObject : AnyObject]?) -> Void in 
        if thumbnail == true { 
         self.libraryImageThumbnails.append(image!) 
         self.collectionTable.reloadData() 
        } else { 
         self.libraryImages.append(image!) 
         self.collectionTable.reloadData() 

        } 
      }) 

      /* The image is now available to us */ 

      print("enum for image, This is number 2") 



      print("Inside If object is PHAsset, This is number 3") 
     } 
     print("Outside If object is PHAsset, This is number 4") 

    } 



} 

請告訴我,如果需要更多的信息。謝謝!

+0

是的,1000張圖像可能會佔用很多內存......這是什麼問題? – jtbandes

+0

@jtbandes我如何檢索這些1000像Instagram的圖像呢? –

+0

延遲加載,每次加載內存中的30個圖像,當用戶滾動加載下一個設置時,刪除前一個。 – Shubhank

回答

0

在CellForRowAtIndexPath中,使用PHImageManager的RequestImageForAsset方法在您的UIImageView上延遲加載圖像屬性。

0

一般你不要想要加載噸的全尺寸或屏幕大小的圖像,並保持他們自己的記憶。對於這種尺寸,您一次只能呈現一個(或兩個或三個,如果要預加載屏幕轉換動畫),因此您不需要一次獲取超過一個。

同樣,加載數百或數千個縮略圖並自己緩存它們會導致內存問題。 (一次又一次地反覆收集視圖到reloadData也會導致大量流失。)相反,讓Photos框架管理它們 - 它具有確保只在需要時生成縮略圖並在使用之間進行緩存的功能,甚至可以幫助您執行任務,例如只抓取用戶在集合視圖中滾動時所需的縮略圖。

Apple的Using Photos Framework示例代碼項目顯示了幾個獲取圖像的最佳實踐。下面是一些主要觀點總結:

  1. AssetGridViewController,管理縮略圖集合視圖,將緩存在初始化時給了它一個PHFetchResult<PHAsset>。有關獲取結果的信息(如其計數)是集合視圖的基本管理所需的全部信息。

  2. AssetGridViewController分別請求來自PHImageManager的縮略圖圖像,僅當收集視圖要求顯示單元格時。這意味着當我們知道一個單元格將被看到時,我們只創建一個UIImage,並且我們不必告訴集合視圖重新加載所有內容。

第2步本身就會導致滾動緩慢,或者更確切地說,在您滾動後減緩圖像加載到單元格中的速度。所以,我們也做:

  • 而不是使用PHImageManager.default(),我們保持PHCachingImageManager一個實例,告訴它我們想要的圖像集「預熱」緩存的作爲用戶滾動。

    AssetGridViewController有一些額外的邏輯用於跟蹤滾動視圖的可見矩形,以便圖像管理器知道爲當前可見項目準備縮略圖(加上一點滾動提前),並且可以釋放資源給項目不再可見,如果需要的話。請注意,預取不會創建UIImage,只需從磁盤啓動必要的加載或從iCloud下載,以便您的內存使用量保持較小。

  • 論集視圖中選擇的項目(以原因請看到照片的全屏呈現),AssetViewController使用默認PHImageManager請求屏幕尺寸(未全尺寸)圖像。

    機會性投放意味着我們將立即獲得質量較低的版本(基本上照片已經從之前在集合視圖中的使用中爲我們緩存的相同縮略圖),以及不久之後的較高質量版本之後我們會自動更新視圖)。

    如果您需要支持縮放(示例代碼應用程序不支持,但很可能是真實應用程序),則可以在進入全屏視圖後立即請求全尺寸圖像(在花費較長的時間從吹起的縮略圖轉換爲全屏圖像)或者通過請求屏幕大小的圖像開始,然後請求全尺寸的圖像以供以後交付。