From ec9ce13b1d40a472e6d178d79b3d4350ce2c034b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E4=BA=91=E9=A3=9E?= Date: Tue, 19 Nov 2019 19:38:14 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9UIKit=20=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- QMUIKit/QMUIComponents/QMUIWindowSizeMonitor.h | 2 +- QMUIKit/UIKitExtensions/UIMenuController+QMUI.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/QMUIKit/QMUIComponents/QMUIWindowSizeMonitor.h b/QMUIKit/QMUIComponents/QMUIWindowSizeMonitor.h index 83911a34..760ab805 100644 --- a/QMUIKit/QMUIComponents/QMUIWindowSizeMonitor.h +++ b/QMUIKit/QMUIComponents/QMUIWindowSizeMonitor.h @@ -12,7 +12,7 @@ // Created by ziezheng on 2019/5/27. // -#import +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/QMUIKit/UIKitExtensions/UIMenuController+QMUI.h b/QMUIKit/UIKitExtensions/UIMenuController+QMUI.h index 129d6b3d..1960c185 100644 --- a/QMUIKit/UIKitExtensions/UIMenuController+QMUI.h +++ b/QMUIKit/UIKitExtensions/UIMenuController+QMUI.h @@ -12,7 +12,7 @@ // Created by 陈志宏 on 2019/7/21. // -#import +#import NS_ASSUME_NONNULL_BEGIN From 4b2c12f75335dd002bba6a6f8e2cdb0e138bbc2c Mon Sep 17 00:00:00 2001 From: "yunfei.fan" Date: Wed, 22 Jul 2020 10:27:12 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=98=E5=8C=96QMUIAsset=20=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=8E=9F=E5=A7=8B=E7=85=A7=E7=89=87=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=88requestOriginImageWithCompletion=EF=BC=89?= =?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3=E9=A2=84=E8=A7=88=E5=A4=A7=E5=9B=BE?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E5=8D=A1=E9=A1=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../QMUIComponents/AssetLibrary/QMUIAsset.h | 2 + .../QMUIComponents/AssetLibrary/QMUIAsset.m | 56 +++++++++++++++++++ .../QMUIImagePickerPreviewViewController.m | 30 +++++++++- 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h index d5feb500..b43f5da7 100644 --- a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h +++ b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h @@ -78,6 +78,8 @@ typedef NS_ENUM(NSUInteger, QMUIAssetDownloadStatus) { */ - (UIImage *)previewImage; +- (NSInteger)requestOriginalImageWithCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed; + /** * 异步请求 Asset 的原图,包含了系统照片“编辑”功能处理后的效果(剪裁,旋转和滤镜等),可能会有网络请求 * diff --git a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m index c1f7500a..8b13dc26 100644 --- a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m +++ b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m @@ -117,6 +117,62 @@ - (UIImage *)previewImage { return resultImage; } +- (NSInteger)requestOriginalImageWithCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed { + CGFloat aspectRatio = _phAsset.pixelWidth / (CGFloat)_phAsset.pixelHeight; + CGFloat pixelWidth = [UIScreen mainScreen].bounds.size.width * ScreenScale; + // 超宽图片 + if (aspectRatio > 1.8) { + pixelWidth = pixelWidth * aspectRatio; + } + // 超高图片 + if (aspectRatio < 0.2) { + pixelWidth = pixelWidth * 0.5; + } + CGFloat pixelHeight = pixelWidth / aspectRatio; + CGSize imageSize = CGSizeMake(pixelWidth, pixelHeight); + + // 修复获取图片时出现的瞬间内存过高问题 + // 下面两行代码,来自hsjcom,他的github是:https://github.com/hsjcom 表示感谢 + PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init]; + option.resizeMode = PHImageRequestOptionsResizeModeFast; + __weak typeof(self) weakSelf = self; + int32_t imageRequestID = [[PHImageManager defaultManager] requestImageForAsset:_phAsset targetSize:imageSize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage *result, NSDictionary *info) { + __strong typeof(weakSelf) strongSelf = weakSelf; + if (!strongSelf) { + return; + } + BOOL cancelled = [[info objectForKey:PHImageCancelledKey] boolValue]; + if (!cancelled && result) { + if (completion) { + completion(result,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]); + } + } + // Download image from iCloud / 从iCloud下载图片 + if ([info objectForKey:PHImageResultIsInCloudKey] && !result && networkAccessAllowed) { + PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; + options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (progressHandler) { + progressHandler(progress, error, stop, info); + } + }); + }; + options.networkAccessAllowed = YES; + options.resizeMode = PHImageRequestOptionsResizeModeFast; + [[PHImageManager defaultManager] requestImageDataForAsset:strongSelf.phAsset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { + UIImage *resultImage = [UIImage imageWithData:imageData]; + if (!resultImage && result) { + resultImage = result; + } + if (completion) { + completion(resultImage,info,NO); + } + }]; + } + }]; + return imageRequestID; +} + - (NSInteger)requestOriginImageWithCompletion:(void (^)(UIImage *result, NSDictionary *info))completion withProgressHandler:(PHAssetImageProgressHandler)phProgressHandler { PHImageRequestOptions *imageRequestOptions = [[PHImageRequestOptions alloc] init]; imageRequestOptions.networkAccessAllowed = YES; // 允许访问网络 diff --git a/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m b/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m index 3df99cb7..b54263d8 100644 --- a/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m +++ b/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m @@ -404,7 +404,33 @@ - (void)requestImageForZoomImageView:(QMUIZoomImageView *)zoomImageView withInde } else { imageView.tag = -1; imageView.image = [imageAsset thumbnailWithSize:CGSizeMake([QMUIImagePickerViewController appearance].minimumImageWidth, [QMUIImagePickerViewController appearance].minimumImageWidth)]; - imageAsset.requestID = [imageAsset requestOriginImageWithCompletion:^void(UIImage *result, NSDictionary *info) { +// imageAsset.requestID = [imageAsset requestOriginImageWithCompletion:^void(UIImage *result, NSDictionary *info) { +// // 这里可能因为 imageView 复用,导致前面的请求得到的结果显示到别的 imageView 上, +// // 因此判断如果是新请求(无复用问题)或者是当前的请求才把获得的图片结果展示出来 +// dispatch_async(dispatch_get_main_queue(), ^{ +// BOOL isNewRequest = (imageView.tag == -1 && imageAsset.requestID == 0); +// BOOL isCurrentRequest = imageView.tag == imageAsset.requestID; +// BOOL loadICloudImageFault = !result || info[PHImageErrorKey]; +// if (!loadICloudImageFault && (isNewRequest || isCurrentRequest)) { +// imageView.image = result; +// } +// BOOL downloadSucceed = (result && !info) || (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue]); +// if (downloadSucceed) { +// // 资源资源已经在本地或下载成功 +// [imageAsset updateDownloadStatusWithDownloadResult:YES]; +// self.downloadStatus = QMUIAssetDownloadStatusSucceed; +// imageView.cloudDownloadStatus = QMUIAssetDownloadStatusSucceed; +// } else if ([info objectForKey:PHImageErrorKey] ) { +// // 下载错误 +// [imageAsset updateDownloadStatusWithDownloadResult:NO]; +// self.downloadStatus = QMUIAssetDownloadStatusFailed; +// imageView.cloudDownloadStatus = QMUIAssetDownloadStatusFailed; +// } +// }); +// } withProgressHandler:phProgressHandler]; + + //FIXME:优化QMUIAsset 获取原始照片的方法(requestOriginImageWithCompletion),解决预览大图时的卡顿 + imageAsset.requestID = [imageAsset requestOriginalImageWithCompletion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) { // 这里可能因为 imageView 复用,导致前面的请求得到的结果显示到别的 imageView 上, // 因此判断如果是新请求(无复用问题)或者是当前的请求才把获得的图片结果展示出来 dispatch_async(dispatch_get_main_queue(), ^{ @@ -427,7 +453,7 @@ - (void)requestImageForZoomImageView:(QMUIZoomImageView *)zoomImageView withInde imageView.cloudDownloadStatus = QMUIAssetDownloadStatusFailed; } }); - } withProgressHandler:phProgressHandler]; + } progressHandler:phProgressHandler networkAccessAllowed:YES]; imageView.tag = imageAsset.requestID; } } From 82e76f0e6764e40c5249bff3bc2096a3f909efcd Mon Sep 17 00:00:00 2001 From: "yunfei.fan" Date: Thu, 23 Jul 2020 09:12:54 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h | 2 +- QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m | 2 +- .../QMUIImagePickerPreviewViewController.m | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h index b43f5da7..b8e1f9bd 100644 --- a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h +++ b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.h @@ -78,7 +78,7 @@ typedef NS_ENUM(NSUInteger, QMUIAssetDownloadStatus) { */ - (UIImage *)previewImage; -- (NSInteger)requestOriginalImageWithCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed; +- (NSInteger)requestOriginalImageWithCompletion:(void (^)(UIImage *image,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed; /** * 异步请求 Asset 的原图,包含了系统照片“编辑”功能处理后的效果(剪裁,旋转和滤镜等),可能会有网络请求 diff --git a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m index 8b13dc26..fdadd737 100644 --- a/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m +++ b/QMUIKit/QMUIComponents/AssetLibrary/QMUIAsset.m @@ -117,7 +117,7 @@ - (UIImage *)previewImage { return resultImage; } -- (NSInteger)requestOriginalImageWithCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed { +- (NSInteger)requestOriginalImageWithCompletion:(void (^)(UIImage *image,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed { CGFloat aspectRatio = _phAsset.pixelWidth / (CGFloat)_phAsset.pixelHeight; CGFloat pixelWidth = [UIScreen mainScreen].bounds.size.width * ScreenScale; // 超宽图片 diff --git a/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m b/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m index b54263d8..0b7ce964 100644 --- a/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m +++ b/QMUIKit/QMUIComponents/ImagePickerLibrary/QMUIImagePickerPreviewViewController.m @@ -430,17 +430,17 @@ - (void)requestImageForZoomImageView:(QMUIZoomImageView *)zoomImageView withInde // } withProgressHandler:phProgressHandler]; //FIXME:优化QMUIAsset 获取原始照片的方法(requestOriginImageWithCompletion),解决预览大图时的卡顿 - imageAsset.requestID = [imageAsset requestOriginalImageWithCompletion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) { + imageAsset.requestID = [imageAsset requestOriginalImageWithCompletion:^(UIImage *image, NSDictionary *info, BOOL isDegraded) { // 这里可能因为 imageView 复用,导致前面的请求得到的结果显示到别的 imageView 上, // 因此判断如果是新请求(无复用问题)或者是当前的请求才把获得的图片结果展示出来 dispatch_async(dispatch_get_main_queue(), ^{ BOOL isNewRequest = (imageView.tag == -1 && imageAsset.requestID == 0); BOOL isCurrentRequest = imageView.tag == imageAsset.requestID; - BOOL loadICloudImageFault = !result || info[PHImageErrorKey]; + BOOL loadICloudImageFault = !image || info[PHImageErrorKey]; if (!loadICloudImageFault && (isNewRequest || isCurrentRequest)) { - imageView.image = result; + imageView.image = image; } - BOOL downloadSucceed = (result && !info) || (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue]); + BOOL downloadSucceed = (image && !info) || (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue]); if (downloadSucceed) { // 资源资源已经在本地或下载成功 [imageAsset updateDownloadStatusWithDownloadResult:YES];