This commit is contained in:
DDIsFriend
2023-08-18 17:28:57 +08:00
commit f0e8a1709d
4282 changed files with 192396 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
//
// ZLFetchImageOperation.swift
// ZLPhotoBrowser
//
// Created by long on 2020/8/18.
//
// Copyright (c) 2020 Long Zhang <495181165@qq.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import UIKit
import Photos
class ZLFetchImageOperation: Operation {
private let model: ZLPhotoModel
private let isOriginal: Bool
private let progress: ((CGFloat, Error?, UnsafeMutablePointer<ObjCBool>, [AnyHashable: Any]?) -> Void)?
private let completion: (UIImage?, PHAsset?) -> Void
private var pri_isExecuting = false {
willSet {
self.willChangeValue(forKey: "isExecuting")
}
didSet {
self.didChangeValue(forKey: "isExecuting")
}
}
override var isExecuting: Bool {
return pri_isExecuting
}
private var pri_isFinished = false {
willSet {
self.willChangeValue(forKey: "isFinished")
}
didSet {
self.didChangeValue(forKey: "isFinished")
}
}
override var isFinished: Bool {
return pri_isFinished
}
private var pri_isCancelled = false {
willSet {
willChangeValue(forKey: "isCancelled")
}
didSet {
didChangeValue(forKey: "isCancelled")
}
}
private var requestImageID: PHImageRequestID = PHInvalidImageRequestID
override var isCancelled: Bool {
return pri_isCancelled
}
init(
model: ZLPhotoModel,
isOriginal: Bool,
progress: ((CGFloat, Error?, UnsafeMutablePointer<ObjCBool>, [AnyHashable: Any]?) -> Void)? = nil,
completion: @escaping ((UIImage?, PHAsset?) -> Void)
) {
self.model = model
self.isOriginal = isOriginal
self.progress = progress
self.completion = completion
super.init()
}
override func start() {
if isCancelled {
fetchFinish()
return
}
zl_debugPrint("---- start fetch")
pri_isExecuting = true
//
if let editImage = model.editImage {
if ZLPhotoConfiguration.default().saveNewImageAfterEdit {
ZLPhotoManager.saveImageToAlbum(image: editImage) { [weak self] _, asset in
self?.completion(editImage, asset)
self?.fetchFinish()
}
} else {
ZLMainAsync {
self.completion(editImage, nil)
self.fetchFinish()
}
}
return
}
if ZLPhotoConfiguration.default().allowSelectGif, model.type == .gif {
requestImageID = ZLPhotoManager.fetchOriginalImageData(for: model.asset) { [weak self] data, _, isDegraded in
if !isDegraded {
let image = UIImage.zl.animateGifImage(data: data)
self?.completion(image, nil)
self?.fetchFinish()
}
}
return
}
if isOriginal {
requestImageID = ZLPhotoManager.fetchOriginalImage(for: model.asset, progress: progress) { [weak self] image, isDegraded in
if !isDegraded {
zl_debugPrint("---- 原图加载完成 \(String(describing: self?.isCancelled))")
self?.completion(image?.zl.fixOrientation(), nil)
self?.fetchFinish()
}
}
} else {
requestImageID = ZLPhotoManager.fetchImage(for: model.asset, size: model.previewSize, progress: progress) { [weak self] image, isDegraded in
if !isDegraded {
zl_debugPrint("---- 加载完成 isCancelled: \(String(describing: self?.isCancelled))")
self?.completion(self?.scaleImage(image?.zl.fixOrientation()), nil)
self?.fetchFinish()
}
}
}
}
override func cancel() {
super.cancel()
zl_debugPrint("---- cancel \(isExecuting) \(requestImageID)")
PHImageManager.default().cancelImageRequest(requestImageID)
pri_isCancelled = true
if isExecuting {
fetchFinish()
}
}
private func scaleImage(_ image: UIImage?) -> UIImage? {
guard let i = image else {
return nil
}
guard let data = i.jpegData(compressionQuality: 1) else {
return i
}
let mUnit: CGFloat = 1024 * 1024
if data.count < Int(0.2 * mUnit) {
return i
}
let scale: CGFloat = (data.count > Int(mUnit) ? 0.6 : 0.8)
guard let d = i.jpegData(compressionQuality: scale) else {
return i
}
return UIImage(data: d)
}
private func fetchFinish() {
pri_isExecuting = false
pri_isFinished = true
}
}