     @objc private func downloadOriginalImage() {
         if let extraInfo = self.item.extraInfo, let originalURL = extraInfo[DKPhotoGalleryItemExtraInfoKeyRemoteImageOriginalURL] as? NSURL {
             self.downloadOriginalImageButton.isEnabled = false
+
+            let reuseIdentifier = self.reuseIdentifier
             
             self.downloadImage(with: originalURL, progressBlock: { [weak self] (progress) in
+                guard reuseIdentifier == self?.reuseIdentifier else { return }
+                
                 self?.updateDownloadOriginalButton(with: progress)
-            }, completeBlock: { (data, error) in
+            }, completeBlock: { [weak self] (data, error) in
+                guard reuseIdentifier == self?.reuseIdentifier else { return }
+                
                 if error == nil {
-                    self.setNeedsUpdateContent()
-                    self.downloadOriginalImageButton.isHidden = true
+                    self?.setNeedsUpdateContent()
+                    self?.downloadOriginalImageButton.isHidden = true
                 } else {
-                    self.downloadOriginalImageButton.isEnabled = true
-                    self.updateDownloadOriginalButtonTitle()
+                    self?.downloadOriginalImageButton.isEnabled = true
+                    self?.updateDownloadOriginalButtonTitle()
                 }
             })
         }
     }
     
-    private func downloadImage(with URL: NSURL, progressBlock: @escaping ((_ progress: Float) -> Void),
+    private func updateDownloadOriginalButtonTitle() {
+        if let extraInfo = self.item.extraInfo, let fileSize = extraInfo[DKPhotoGalleryItemExtraInfoKeyRemoteImageOriginalSize] as? NSNumber {
+            self.downloadOriginalImageButton.setTitle("下载原图(\(self.formattedFileSize(fileSize.uintValue)))", for: .normal)
+        } else {
+            self.downloadOriginalImageButton.setTitle("下载原图", for: .normal)
+        }
+        self.updateDownloadOriginalButtonFrame()
+    }
+    
+    private func updateDownloadOriginalButton(with progress: Float) {
+        if progress > 0 {
+            self.downloadOriginalImageButton.setTitle(String(format: "%.0f%%", progress * 100), for: .normal)
+            self.updateDownloadOriginalButtonFrame()
+        }
+    }
+    
+    private func updateDownloadOriginalButtonFrame() {
+        self.downloadOriginalImageButton.sizeToFit()
+        
+        let buttonWidth = max(100, self.downloadOriginalImageButton.bounds.width)
+        let buttonHeight = CGFloat(25)
+        
+        self.downloadOriginalImageButton.frame = CGRect(x: (self.view.bounds.width - buttonWidth) / 2,
+                                                        y: self.view.bounds.height - buttonHeight - 20,
+                                                        width: buttonWidth,
+                                                        height: buttonHeight)
+    }
+    
+    private func formattedFileSize(_ fileSize: UInt) -> String {
+        let tokens = ["B", "KB", "MB", "GB", "TB"]
+        
+        var convertedSize = Double(fileSize)
+        var factor = 0
+        
+        while convertedSize > 1024 {
+            convertedSize = convertedSize / 1024
+            factor = factor + 1
+        }
+        
+        if factor == 0 {
+            return String(format: "%4.0f%@", convertedSize, tokens[factor])
+        } else {
+            return String(format: "%4.2f%@", convertedSize, tokens[factor])
+        }
+    }
+    
+    // MARK: - Fetch Image
+    
+    private func asyncFetchImage(with identifier: Any,
+                                 progressBlock: @escaping ((_ progress: Float) -> Void),
+                                 completeBlock: @escaping ((_ data: Any?, _ error: Error?) -> Void)) {
+        if let downloadURL = identifier as? URL, downloadURL.isFileURL {
+            self.asyncFetchLocalImage(with: downloadURL as URL, completeBlock: completeBlock)
+        } else {
+            self.downloadImage(with: identifier, progressBlock: progressBlock, completeBlock: completeBlock)
+        }
+    }
+    
+    static let ioQueue = DispatchQueue(label: "DKPhotoImagePreviewVC.ioQueue")
+    private func asyncFetchLocalImage(with URL: URL, completeBlock: @escaping ((_ data: Any?, _ error: Error?) -> Void)) {
+        DKPhotoImagePreviewVC.ioQueue.async {
+            let key = URL.absoluteString
+            
+            var error: Error?
+            var image = SDImageCache.shared().imageFromMemoryCache(forKey: key)
+            
+            if image == nil {
+                if let imageData = NSData(contentsOf: URL) {
+                    image = SDWebImageCodersManager.sharedInstance().decodedImage(with: imageData as Data)
+                    SDImageCache.shared().store(image, forKey: key, toDisk: false, completion: nil)
+                } else {
+                    error = NSError(domain: Bundle.main.bundleIdentifier!, code: -1, userInfo: [
+                        NSLocalizedDescriptionKey : "获取图片失败"
+                        ])
+                }
+            }
+            
+            completeBlock(image, error)
+        }
+    }
+    
+    private func downloadImage(with identifier: Any,
+                               progressBlock: @escaping ((_ progress: Float) -> Void),
                                completeBlock: @escaping ((_ data: Any?, _ error: Error?) -> Void)) {
-        let key = URL.absoluteString
-        let reuseIdentifier = self.reuseIdentifier!
+        var key = ""
+        var downloader: DKPhotoImageDownloader! = nil
+        if let URL = identifier as? URL {
+            key = URL.absoluteString
+            downloader = DKPhotoImageWebDownloader.downloader()
+        } else if let asset = identifier as? PHAsset {
+            key = asset.localIdentifier
+            downloader = DKPhotoImageAssetDownloader.downloader()
+        } else {
+            assert(false)
+        }
         
         SDImageCache.shared().queryCacheOperation(forKey: key) { (image, data, cacheType) in
             if image != nil || data != nil {
                 completeBlock(image ?? data, nil)
             } else {
-                SDWebImageDownloader.shared().downloadImage(with: URL as URL,
-                                                            options: SDWebImageDownloaderOptions.lowPriority,
-                                                            progress: { [weak self] (receivedSize, expectedSize, targetURL) in
-                                                                guard let strongSelf = self, reuseIdentifier == strongSelf.reuseIdentifier else { return }
-                                                                
-                                                                DispatchQueue.main.async {
-                                                                    progressBlock(Float(receivedSize) / Float(expectedSize))
-                                                                }
-                    }, completed: { [weak self] (image, data, error, finished) in
-                        var success = false
-                        if (image != nil || data != nil) && finished {
-                            SDImageCache.shared().store(image, imageData: data, forKey: key, toDisk: true, completion: nil)
-                            success = true
-                        } else {
-                            success = false
-                        }
+                downloader.downloadImage(with: identifier, progressBlock: { (progress) in
+                    progressBlock(progress)
+                }, completeBlock: { (image, data, error) in
+                    if error == nil {
+                        SDImageCache.shared().store(image, imageData: data, forKey: key, toDisk: true, completion: nil)
                         
-                        guard let strongSelf = self, reuseIdentifier == strongSelf.reuseIdentifier else { return }
-                        
-                        if success {
-                            completeBlock(image ?? data, nil)
-                        } else {
-                            let error = NSError(domain: Bundle.main.bundleIdentifier!, code: -1, userInfo: [
-                                NSLocalizedDescriptionKey : "获取图片失败"
-                                ])
-                            completeBlock(nil, error)
-                        }
+                        completeBlock(image ?? data, nil)
+                    } else {
+                        completeBlock(nil, error)
+                    }
                 })
             }
-        }
-    }
-    
-    private func updateDownloadOriginalButtonTitle() {
-        if let extraInfo = self.item.extraInfo, let fileSize = extraInfo[DKPhotoGalleryItemExtraInfoKeyRemoteImageOriginalSize] as? NSNumber {
-            self.downloadOriginalImageButton.setTitle("下载原图(\(self.formattedFileSize(fileSize.uintValue)))", for: .normal)
-        } else {
-            self.downloadOriginalImageButton.setTitle("下载原图", for: .normal)
-        }
-        self.updateDownloadOriginalButtonFrame()
-    }
-    
-    private func updateDownloadOriginalButton(with progress: Float) {
-        if progress > 0 {
-            self.downloadOriginalImageButton.setTitle(String(format: "%.0f%%", progress * 100), for: .normal)
-            self.updateDownloadOriginalButtonFrame()
-        }
-    }
-    
-    private func updateDownloadOriginalButtonFrame() {
-        self.downloadOriginalImageButton.sizeToFit()
-        
-        let buttonWidth = max(100, self.downloadOriginalImageButton.bounds.width)
-        let buttonHeight = CGFloat(25)
-        
-        self.downloadOriginalImageButton.frame = CGRect(x: (self.view.bounds.width - buttonWidth) / 2,
-                                                        y: self.view.bounds.height - buttonHeight - 20,
-                                                        width: buttonWidth,
-                                                        height: buttonHeight)
-    }
-    
-    private func formattedFileSize(_ fileSize: UInt) -> String {
-        let tokens = ["B", "KB", "MB", "GB", "TB"]
-        
-        var convertedSize = Double(fileSize)
-        var factor = 0
-        
-        while convertedSize > 1024 {
-            convertedSize = convertedSize / 1024
-            factor = factor + 1
-        }
-        
-        if factor == 0 {
-            return String(format: "%4.0f%@", convertedSize, tokens[factor])
-        } else {
-            return String(format: "%4.2f%@", convertedSize, tokens[factor])
         }
     }
     


import UIKit
import SDWebImage

class DKPhotoImagePreviewVC: DKPhotoBaseImagePreviewVC {

    private var image: UIImage?
    private var downloadURL: NSURL?
    
    private var reuseIdentifier: Int? // hash
    

        self.reuseIdentifier = nil
        self.downloadURL = nil
        self.image = nil
        self.asset = nil
        self.downloadOriginalImageButton.isHidden = true
    }
    
}
