Commit a7a3987f authored by banchichen's avatar banchichen

准备适配GIF图片

parent 7b5944f0
Pod::Spec.new do |s|
s.name = "TZImagePickerController"
s.version = "1.7.5"
s.version = "1.7.6"
s.summary = "A clone of UIImagePickerController, support picking multiple photos、original photo and video"
s.homepage = "https://github.com/banchichen/TZImagePickerController"
s.license = "MIT"
s.author = { "banchichen" => "tanzhenios@foxmail.com" }
s.platform = :ios
s.ios.deployment_target = "6.0"
s.source = { :git => "https://github.com/banchichen/TZImagePickerController.git", :tag => "1.7.5" }
s.source = { :git => "https://github.com/banchichen/TZImagePickerController.git", :tag => "1.7.6" }
s.requires_arc = true
s.resources = "TZImagePickerController/TZImagePickerController/*.{png,xib,nib,bundle}"
s.source_files = "TZImagePickerController/TZImagePickerController/*.{h,m}"
......
......@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
6D32B9BD1CD83640005CE1E0 /* LxGridViewFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D32B9BC1CD83640005CE1E0 /* LxGridViewFlowLayout.m */; };
6D4608311DFFC60D004FB009 /* TZGifPhotoPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D4608301DFFC60D004FB009 /* TZGifPhotoPreviewController.m */; };
6D5358CD1D64600F00928CC6 /* NSBundle+TZImagePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D5358CC1D64600F00928CC6 /* NSBundle+TZImagePicker.m */; };
6DC358661CC8BAFD00898D29 /* TZImagePickerController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6DC358651CC8BAFD00898D29 /* TZImagePickerController.bundle */; };
6DC84D0A1DF5358500A107A9 /* TZImageCropManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DC84D091DF5358500A107A9 /* TZImageCropManager.m */; };
......@@ -54,6 +55,8 @@
6D12FC1A1D66B71E00182C44 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
6D32B9BB1CD83640005CE1E0 /* LxGridViewFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LxGridViewFlowLayout.h; sourceTree = "<group>"; };
6D32B9BC1CD83640005CE1E0 /* LxGridViewFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LxGridViewFlowLayout.m; sourceTree = "<group>"; };
6D46082F1DFFC60D004FB009 /* TZGifPhotoPreviewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TZGifPhotoPreviewController.h; sourceTree = "<group>"; };
6D4608301DFFC60D004FB009 /* TZGifPhotoPreviewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TZGifPhotoPreviewController.m; sourceTree = "<group>"; };
6D5358CB1D64600F00928CC6 /* NSBundle+TZImagePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+TZImagePicker.h"; sourceTree = "<group>"; };
6D5358CC1D64600F00928CC6 /* NSBundle+TZImagePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+TZImagePicker.m"; sourceTree = "<group>"; };
6DC358651CC8BAFD00898D29 /* TZImagePickerController.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TZImagePickerController.bundle; sourceTree = "<group>"; };
......@@ -216,6 +219,8 @@
900EF0141C2C134900EA709B /* TZPhotoPreviewCell.m */,
90CE84B51C3BABB6003D0779 /* TZVideoPlayerController.h */,
90CE84B61C3BABB6003D0779 /* TZVideoPlayerController.m */,
6D46082F1DFFC60D004FB009 /* TZGifPhotoPreviewController.h */,
6D4608301DFFC60D004FB009 /* TZGifPhotoPreviewController.m */,
6DD050291DF659ED0057C78D /* TZProgressView.h */,
6DD0502A1DF659ED0057C78D /* TZProgressView.m */,
90CE84AC1C3A89EF003D0779 /* TZImageManager.h */,
......@@ -371,6 +376,7 @@
900EF0021C2BD7E400EA709B /* TZAssetCell.m in Sources */,
6DD0502B1DF659ED0057C78D /* TZProgressView.m in Sources */,
6D32B9BD1CD83640005CE1E0 /* LxGridViewFlowLayout.m in Sources */,
6D4608311DFFC60D004FB009 /* TZGifPhotoPreviewController.m in Sources */,
900EF0161C2C134900EA709B /* TZPhotoPreviewCell.m in Sources */,
900E65871C2BB8D5003D9A9E /* ViewController.m in Sources */,
90CE84AE1C3A89EF003D0779 /* TZImageManager.m in Sources */,
......
......@@ -12,6 +12,7 @@
typedef enum : NSUInteger {
TZAssetCellTypePhoto = 0,
TZAssetCellTypeLivePhoto,
TZAssetCellTypePhotoGif,
TZAssetCellTypeVideo,
TZAssetCellTypeAudio,
} TZAssetCellType;
......@@ -23,6 +24,7 @@ typedef enum : NSUInteger {
@property (nonatomic, strong) TZAssetModel *model;
@property (nonatomic, copy) void (^didSelectPhotoBlock)(BOOL);
@property (nonatomic, assign) TZAssetCellType type;
@property (nonatomic, assign) BOOL allowPickingGif;
@property (nonatomic, copy) NSString *representedAssetIdentifier;
@property (nonatomic, assign) PHImageRequestID imageRequestID;
......
......@@ -19,7 +19,7 @@
@property (weak, nonatomic) UIView *bottomView;
@property (weak, nonatomic) UILabel *timeLength;
@property (nonatomic, weak) UIImageView *viewImgView;
@property (nonatomic, weak) UIImageView *videoImgView;
@property (nonatomic, strong) TZProgressView *progressView;
@property (nonatomic, assign) PHImageRequestID bigImageRequestID;
@end
......@@ -57,14 +57,7 @@
self.imageRequestID = imageRequestID;
self.selectPhotoButton.selected = model.isSelected;
self.selectImageView.image = self.selectPhotoButton.isSelected ? [UIImage imageNamedFromMyBundle:self.photoSelImageName] : [UIImage imageNamedFromMyBundle:self.photoDefImageName];
self.type = TZAssetCellTypePhoto;
if (model.type == TZAssetModelMediaTypeLivePhoto) self.type = TZAssetCellTypeLivePhoto;
else if (model.type == TZAssetModelMediaTypeAudio) self.type = TZAssetCellTypeAudio;
else if (model.type == TZAssetModelMediaTypeVideo) {
self.type = TZAssetCellTypeVideo;
self.timeLength.text = model.timeLength;
}
self.type = (NSInteger)model.type;
// 让宽度/高度小于 最小可选照片尺寸 的图片不能选中
if (![[TZImageManager manager] isPhotoSelectableWithAsset:model.asset]) {
if (_selectImageView.hidden == NO) {
......@@ -90,14 +83,25 @@
- (void)setType:(TZAssetCellType)type {
_type = type;
if (type == TZAssetCellTypePhoto || type == TZAssetCellTypeLivePhoto) {
if (type == TZAssetCellTypePhoto || type == TZAssetCellTypeLivePhoto || (type == TZAssetCellTypePhotoGif && !self.allowPickingGif)) {
_selectImageView.hidden = NO;
_selectPhotoButton.hidden = NO;
_bottomView.hidden = YES;
} else {
} else { // Video of Gif
_selectImageView.hidden = YES;
_selectPhotoButton.hidden = YES;
_bottomView.hidden = NO;
if (type == TZAssetCellTypeVideo) {
self.timeLength.text = _model.timeLength;
self.videoImgView.hidden = NO;
_timeLength.tz_left = self.videoImgView.tz_right;
_timeLength.textAlignment = NSTextAlignmentRight;
} else {
self.timeLength.text = @"GIF";
self.videoImgView.hidden = YES;
_timeLength.tz_left = 5;
_timeLength.textAlignment = NSTextAlignmentLeft;
}
}
}
......@@ -183,30 +187,30 @@
if (_bottomView == nil) {
UIView *bottomView = [[UIView alloc] init];
bottomView.frame = CGRectMake(0, self.tz_height - 17, self.tz_width, 17);
bottomView.backgroundColor = [UIColor blackColor];
bottomView.alpha = 0.8;
static NSInteger rgb = 0;
bottomView.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.8];
[self.contentView addSubview:bottomView];
_bottomView = bottomView;
}
return _bottomView;
}
- (UIImageView *)viewImgView {
if (_viewImgView == nil) {
UIImageView *viewImgView = [[UIImageView alloc] init];
viewImgView.frame = CGRectMake(8, 0, 17, 17);
[viewImgView setImage:[UIImage imageNamedFromMyBundle:@"VideoSendIcon.png"]];
[self.bottomView addSubview:viewImgView];
_viewImgView = viewImgView;
- (UIImageView *)videoImgView {
if (_videoImgView == nil) {
UIImageView *videoImgView = [[UIImageView alloc] init];
videoImgView.frame = CGRectMake(8, 0, 17, 17);
[videoImgView setImage:[UIImage imageNamedFromMyBundle:@"VideoSendIcon.png"]];
[self.bottomView addSubview:videoImgView];
_videoImgView = videoImgView;
}
return _viewImgView;
return _videoImgView;
}
- (UILabel *)timeLength {
if (_timeLength == nil) {
UILabel *timeLength = [[UILabel alloc] init];
timeLength.font = [UIFont boldSystemFontOfSize:11];
timeLength.frame = CGRectMake(self.viewImgView.tz_right, 0, self.tz_width - self.viewImgView.tz_right - 5, 17);
timeLength.frame = CGRectMake(self.videoImgView.tz_right, 0, self.tz_width - self.videoImgView.tz_right - 5, 17);
timeLength.textColor = [UIColor whiteColor];
timeLength.textAlignment = NSTextAlignmentRight;
[self.bottomView addSubview:timeLength];
......
......@@ -12,6 +12,7 @@
typedef enum : NSUInteger {
TZAssetModelMediaTypePhoto = 0,
TZAssetModelMediaTypeLivePhoto,
TZAssetModelMediaTypePhotoGif,
TZAssetModelMediaTypeVideo,
TZAssetModelMediaTypeAudio
} TZAssetModelMediaType;
......
//
// TZGifPhotoPreviewController.h
// TZImagePickerController
//
// Created by ttouch on 2016/12/13.
// Copyright © 2016年 谭真. All rights reserved.
//
#import <UIKit/UIKit.h>
@class TZAssetModel;
@interface TZGifPhotoPreviewController : UIViewController
@property (nonatomic, strong) TZAssetModel *model;
@end
//
// TZGifPhotoPreviewController.m
// TZImagePickerController
//
// Created by ttouch on 2016/12/13.
// Copyright © 2016年 谭真. All rights reserved.
//
#import "TZGifPhotoPreviewController.h"
#import "TZImagePickerController.h"
#import "TZAssetModel.h"
#import "UIView+Layout.h"
#import "TZPhotoPreviewCell.h"
@interface TZGifPhotoPreviewController () {
UIView *_toolBar;
UIButton *_doneButton;
UIProgressView *_progress;
TZPhotoPreviewView *_previewView;
}
@end
@implementation TZGifPhotoPreviewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
self.navigationItem.title = [NSString stringWithFormat:@"GIF%@",tzImagePickerVc.previewBtnTitleStr];
[self configPreviewView];
[self configBottomToolBar];
}
- (void)configPreviewView {
_previewView = [[TZPhotoPreviewView alloc] initWithFrame:self.view.bounds];
_previewView.scrollView.frame = self.view.bounds;
_previewView.model = self.model;
__weak typeof(self) weakSelf = self;
[_previewView setSingleTapGestureBlock:^{
[weakSelf signleTapAction];
}];
[self.view addSubview:_previewView];
}
- (void)configBottomToolBar {
_toolBar = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.tz_height - 44, self.view.tz_width, 44)];
CGFloat rgb = 34 / 255.0;
_toolBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:1.0];
_toolBar.alpha = 0.7;
_doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
_doneButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 0, 44, 44);
_doneButton.titleLabel.font = [UIFont systemFontOfSize:16];
[_doneButton addTarget:self action:@selector(doneButtonClick) forControlEvents:UIControlEventTouchUpInside];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
[_doneButton setTitle:tzImagePickerVc.doneBtnTitleStr forState:UIControlStateNormal];
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[_doneButton setTitleColor:imagePickerVc.oKButtonTitleColorNormal forState:UIControlStateNormal];
[_toolBar addSubview:_doneButton];
[self.view addSubview:_toolBar];
}
#pragma mark - Click Event
- (void)signleTapAction {
_toolBar.hidden = !_toolBar.isHidden;
[self.navigationController setNavigationBarHidden:_toolBar.isHidden];
if (iOS7Later) [UIApplication sharedApplication].statusBarHidden = _toolBar.isHidden;
}
- (void)doneButtonClick {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
if (self.navigationController) {
if (imagePickerVc.autoDismiss) {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self callDelegateMethod];
}];
}
} else {
[self dismissViewControllerAnimated:YES completion:^{
[self callDelegateMethod];
}];
}
}
- (void)callDelegateMethod {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
UIImage *animatedImage = _previewView.imageView.image;
if ([imagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingGifImage:sourceAssets:)]) {
[imagePickerVc.pickerDelegate imagePickerController:imagePickerVc didFinishPickingGifImage:animatedImage sourceAssets:_model.asset];
}
if (imagePickerVc.didFinishPickingGifImageHandle) {
imagePickerVc.didFinishPickingGifImageHandle(animatedImage,_model.asset);
}
}
@end
......@@ -28,3 +28,12 @@
+ (UIImage *)circularClipImage:(UIImage *)image;
@end
@interface UIImage (TZGif)
- (UIImage *)sd_tz_animatedImageByScalingAndCroppingToSize:(CGSize)size;
+ (UIImage *)sd_tz_animatedGIFWithData:(NSData *)data;
@end
......@@ -8,6 +8,7 @@
#import "TZImageCropManager.h"
#import "UIView+Layout.h"
#import <ImageIO/ImageIO.h>
@implementation TZImageCropManager
......@@ -109,3 +110,120 @@
}
@end
@implementation UIImage (TZGif)
- (UIImage *)sd_tz_animatedImageByScalingAndCroppingToSize:(CGSize)size {
if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) {
return self;
}
CGSize scaledSize = size;
CGPoint thumbnailPoint = CGPointZero;
CGFloat widthFactor = size.width / self.size.width;
CGFloat heightFactor = size.height / self.size.height;
CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor;
scaledSize.width = self.size.width * scaleFactor;
scaledSize.height = self.size.height * scaleFactor;
if (widthFactor > heightFactor) {
thumbnailPoint.y = (size.height - scaledSize.height) * 0.5;
}
else if (widthFactor < heightFactor) {
thumbnailPoint.x = (size.width - scaledSize.width) * 0.5;
}
NSMutableArray *scaledImages = [NSMutableArray array];
for (UIImage *image in self.images) {
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
[image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
[scaledImages addObject:newImage];
UIGraphicsEndImageContext();
}
return [UIImage animatedImageWithImages:scaledImages duration:self.duration];
}
+ (UIImage *)sd_tz_animatedGIFWithData:(NSData *)data {
if (!data) {
return nil;
}
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(source);
UIImage *animatedImage;
if (count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
}
else {
NSMutableArray *images = [NSMutableArray array];
NSTimeInterval duration = 0.0f;
for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
if (!image) {
continue;
}
duration += [self sd_frameDurationAtIndex:i source:source];
[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
CGImageRelease(image);
}
if (!duration) {
duration = (1.0f / 10.0f) * count;
}
animatedImage = [UIImage animatedImageWithImages:images duration:duration];
}
CFRelease(source);
return animatedImage;
}
+ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
float frameDuration = 0.1f;
CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
if (delayTimeUnclampedProp) {
frameDuration = [delayTimeUnclampedProp floatValue];
}
else {
NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
if (delayTimeProp) {
frameDuration = [delayTimeProp floatValue];
}
}
// Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
// We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
// a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
// for more information.
if (frameDuration < 0.011f) {
frameDuration = 0.100f;
}
CFRelease(cfFrameProperties);
return frameDuration;
}
@end
......@@ -60,7 +60,8 @@
/// Get full Image 获取原图
/// 该方法会先返回缩略图,再返回原图,如果info[PHImageResultIsDegradedKey] 为 YES,则表明当前返回的是缩略图,否则是原图。
- (void)getOriginalPhotoWithAsset:(id)asset completion:(void (^)(UIImage *photo,NSDictionary *info))completion;
- (void)getOriginalPhotoDataWithAsset:(id)asset completion:(void (^)(NSData *data,NSDictionary *info))completion;
- (void)getOriginalPhotoWithAsset:(id)asset newCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (void)getOriginalPhotoDataWithAsset:(id)asset completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
/// Save photo 保存照片
- (void)savePhotoWithImage:(UIImage *)image completion:(void (^)(NSError *error))completion;
......
......@@ -61,27 +61,31 @@
/// 超时时间,默认为15秒,当取图片时间超过15秒还没有取成功时,会自动dismiss HUD;
@property (nonatomic, assign) NSInteger timeout;
/// Default is YES.if set NO, the original photo button will hide. user can't picking original photo.
/// Default is YES, if set NO, the original photo button will hide. user can't picking original photo.
/// 默认为YES,如果设置为NO,原图按钮将隐藏,用户不能选择发送原图
@property (nonatomic, assign) BOOL allowPickingOriginalPhoto;
/// Default is YES.if set NO, user can't picking video.
/// 默认为YES,如果设置为NO,用户将不能选择发送视频
/// Default is YES, if set NO, user can't picking video.
/// 默认为YES,如果设置为NO,用户将不能选择视频
@property (nonatomic, assign) BOOL allowPickingVideo;
/// Default is YES.if set NO, user can't picking image.
/// Default is NO, if set YES, user can picking gif image.
/// 默认为NO,如果设置为YES,用户可以选择gif图片
@property (nonatomic, assign) BOOL allowPickingGif;
/// Default is YES, if set NO, user can't picking image.
/// 默认为YES,如果设置为NO,用户将不能选择发送图片
@property(nonatomic, assign) BOOL allowPickingImage;
/// Default is YES.if set NO, user can't take picture.
/// 默认为YES,如果设置为NO,拍照按钮将隐藏,用户将不能在选择器中拍照
/// Default is YES, if set NO, user can't take picture.
/// 默认为YES,如果设置为NO,拍照按钮将隐藏,用户将不能选择照片
@property(nonatomic, assign) BOOL allowTakePicture;
/// Default is YES.if set NO, user can't preview photo.
/// Default is YES, if set NO, user can't preview photo.
/// 默认为YES,如果设置为NO,预览按钮将隐藏,用户将不能去预览照片
@property (nonatomic, assign) BOOL allowPreview;
/// Default is YES.if set NO, the picker don't dismiss itself.
/// Default is YES, if set NO, the picker don't dismiss itself.
/// 默认为YES,如果设置为NO, 选择器将不会自己dismiss
@property(nonatomic, assign) BOOL autoDismiss;
......@@ -149,12 +153,17 @@
@property (nonatomic, copy) void (^didFinishPickingPhotosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto);
@property (nonatomic, copy) void (^didFinishPickingPhotosWithInfosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos);
@property (nonatomic, copy) void (^imagePickerControllerDidCancelHandle)();
// If user picking a video, this handle will be called.
// If system version > iOS8,asset is kind of PHAsset class, else is ALAsset class.
// 如果用户选择了一个视频,下面的handle会被执行
// 如果系统版本大于iOS8,asset是PHAsset类的对象,否则是ALAsset类的对象
@property (nonatomic, copy) void (^didFinishPickingVideoHandle)(UIImage *coverImage,id asset);
// If user picking a gif image, this callback will be called.
// 如果用户选择了一个gif图片,下面的handle会被执行
@property (nonatomic, copy) void (^didFinishPickingGifImageHandle)(UIImage *animatedImage,id sourceAssets);
@property (nonatomic, weak) id<TZImagePickerControllerDelegate> pickerDelegate;
@end
......@@ -182,6 +191,10 @@
// 如果用户选择了一个视频,下面的handle会被执行
// 如果系统版本大于iOS8,asset是PHAsset类的对象,否则是ALAsset类的对象
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingVideo:(UIImage *)coverImage sourceAssets:(id)asset;
// If user picking a gif image, this callback will be called.
// 如果用户选择了一个gif图片,下面的handle会被执行
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingGifImage:(UIImage *)animatedImage sourceAssets:(id)asset;
@end
......
......@@ -14,6 +14,7 @@
#import "UIView+Layout.h"
#import "TZImageManager.h"
#import "TZVideoPlayerController.h"
#import "TZGifPhotoPreviewController.h"
@interface TZPhotoPickerController ()<UICollectionViewDataSource,UICollectionViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIAlertViewDelegate> {
NSMutableArray *_models;
......@@ -364,6 +365,7 @@ static CGSize AssetGridThumbnailSize;
} else {
model = _models[indexPath.row - 1];
}
cell.allowPickingGif = tzImagePickerVc.allowPickingGif;
cell.model = model;
cell.showSelectBtn = tzImagePickerVc.showSelectBtn;
if (!tzImagePickerVc.allowPreview) {
......@@ -425,6 +427,10 @@ static CGSize AssetGridThumbnailSize;
videoPlayerVc.model = model;
[self.navigationController pushViewController:videoPlayerVc animated:YES];
}
} else if (model.type == TZAssetModelMediaTypePhotoGif) {
TZGifPhotoPreviewController *gifPreviewVc = [[TZGifPhotoPreviewController alloc] init];
gifPreviewVc.model = model;
[self.navigationController pushViewController:gifPreviewVc animated:YES];
} else {
TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
photoPreviewVc.currentIndex = index;
......
......@@ -8,13 +8,24 @@
#import <UIKit/UIKit.h>
@class TZAssetModel,TZProgressView;
@class TZAssetModel,TZProgressView,TZPhotoPreviewView;
@interface TZPhotoPreviewCell : UICollectionViewCell
@property (nonatomic, strong) TZAssetModel *model;
@property (nonatomic, copy) void (^singleTapGestureBlock)();
@property (nonatomic, copy) void (^imageProgressUpdateBlock)(double progress);
@property (nonatomic, strong) TZPhotoPreviewView *previewView;
@property (nonatomic, assign) BOOL allowCrop;
@property (nonatomic, assign) CGRect cropRect;
- (void)recoverSubviews;
@end
@interface TZPhotoPreviewView : UIView
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *imageContainerView;
......@@ -23,6 +34,9 @@
@property (nonatomic, assign) BOOL allowCrop;
@property (nonatomic, assign) CGRect cropRect;
- (void)recoverSubviews;
@property (nonatomic, strong) TZAssetModel *model;
@property (nonatomic, copy) void (^singleTapGestureBlock)();
@property (nonatomic, copy) void (^imageProgressUpdateBlock)(double progress);
- (void)recoverSubviews;
@end
......@@ -11,10 +11,9 @@
#import "UIView+Layout.h"
#import "TZImageManager.h"
#import "TZProgressView.h"
#import "TZImageCropManager.h"
@interface TZPhotoPreviewCell ()<UIGestureRecognizerDelegate,UIScrollViewDelegate> {
CGFloat _aspectRatio;
}
@interface TZPhotoPreviewCell ()
@end
@implementation TZPhotoPreviewCell
......@@ -23,6 +22,54 @@
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor blackColor];
self.previewView = [[TZPhotoPreviewView alloc] initWithFrame:self.bounds];
__weak typeof(self) weakSelf = self;
[self.previewView setSingleTapGestureBlock:^{
if (weakSelf.singleTapGestureBlock) {
weakSelf.singleTapGestureBlock();
}
}];
[self.previewView setImageProgressUpdateBlock:^(double progress) {
if (weakSelf.imageProgressUpdateBlock) {
weakSelf.imageProgressUpdateBlock(progress);
}
}];
[self addSubview:self.previewView];
}
return self;
}
- (void)setModel:(TZAssetModel *)model {
_model = model;
_previewView.model = model;
}
- (void)recoverSubviews {
[_previewView recoverSubviews];
}
- (void)setAllowCrop:(BOOL)allowCrop {
_allowCrop = allowCrop;
_previewView.allowCrop = allowCrop;
}
- (void)setCropRect:(CGRect)cropRect {
_cropRect = cropRect;
_previewView.cropRect = cropRect;
}
@end
@interface TZPhotoPreviewView ()<UIScrollViewDelegate>
@end
@implementation TZPhotoPreviewView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_scrollView = [[UIScrollView alloc] init];
_scrollView.frame = CGRectMake(10, 0, self.tz_width - 20, self.tz_height);
_scrollView.bouncesZoom = YES;
......@@ -62,7 +109,6 @@
return self;
}
- (void)configProgressView {
_progressView = [[TZProgressView alloc] init];
static CGFloat progressWH = 40;
......@@ -76,22 +122,31 @@
- (void)setModel:(TZAssetModel *)model {
_model = model;
[_scrollView setZoomScale:1.0 animated:NO];
[[TZImageManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
self.imageView.image = photo;
[self resizeSubviews];
_progressView.hidden = YES;
if (self.imageProgressUpdateBlock) {
self.imageProgressUpdateBlock(1);
}
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
_progressView.hidden = NO;
[self bringSubviewToFront:_progressView];
progress = progress > 0.02 ? progress : 0.02;;
_progressView.progress = progress;
if (self.imageProgressUpdateBlock) {
self.imageProgressUpdateBlock(progress);
}
} networkAccessAllowed:YES];
if (model.type == TZAssetModelMediaTypePhotoGif) {
[[TZImageManager manager] getOriginalPhotoDataWithAsset:model.asset completion:^(NSData *data, NSDictionary *info, BOOL isDegraded) {
if (!isDegraded) {
self.imageView.image = [UIImage sd_tz_animatedGIFWithData:data];
[self resizeSubviews];
}
}];
} else {
[[TZImageManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
self.imageView.image = photo;
[self resizeSubviews];
_progressView.hidden = YES;
if (self.imageProgressUpdateBlock) {
self.imageProgressUpdateBlock(1);
}
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
_progressView.hidden = NO;
[self bringSubviewToFront:_progressView];
progress = progress > 0.02 ? progress : 0.02;;
_progressView.progress = progress;
if (self.imageProgressUpdateBlock) {
self.imageProgressUpdateBlock(progress);
}
} networkAccessAllowed:YES];
}
}
- (void)recoverSubviews {
......
......@@ -292,7 +292,7 @@
if (_tzImagePickerVc.allowCrop) { // 裁剪状态
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:_currentIndex inSection:0];
TZPhotoPreviewCell *cell = (TZPhotoPreviewCell *)[_collectionView cellForItemAtIndexPath:indexPath];
UIImage *cropedImage = [TZImageCropManager cropImageView:cell.imageView toRect:_tzImagePickerVc.cropRect zoomScale:cell.scrollView.zoomScale containerView:self.view];
UIImage *cropedImage = [TZImageCropManager cropImageView:cell.previewView.imageView toRect:_tzImagePickerVc.cropRect zoomScale:cell.previewView.scrollView.zoomScale containerView:self.view];
if (_tzImagePickerVc.needCircleCrop) {
cropedImage = [TZImageCropManager circularClipImage:cropedImage];
}
......
......@@ -13,6 +13,7 @@
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIImageView *videoImageView;
@property (nonatomic, strong) UIButton *deleteBtn;
@property (nonatomic, strong) UILabel *gifLable;
@property (nonatomic, assign) NSInteger row;
@property (nonatomic, strong) id asset;
......
......@@ -36,6 +36,15 @@
_deleteBtn.imageEdgeInsets = UIEdgeInsetsMake(-10, 0, 0, -10);
_deleteBtn.alpha = 0.6;
[self addSubview:_deleteBtn];
_gifLable = [[UILabel alloc] init];
_gifLable.text = @"GIF";
_gifLable.textColor = [UIColor whiteColor];
_gifLable.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.8];
_gifLable.textAlignment = NSTextAlignmentCenter;
_gifLable.font = [UIFont systemFontOfSize:13];
_gifLable.frame = CGRectMake(self.tz_width - 25, self.tz_height - 12, 25, 12);
[self addSubview:_gifLable];
}
return self;
}
......@@ -52,12 +61,11 @@
if ([asset isKindOfClass:[PHAsset class]]) {
PHAsset *phAsset = asset;
_videoImageView.hidden = phAsset.mediaType != PHAssetMediaTypeVideo;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
_gifLable.hidden = ![[phAsset valueForKey:@"filename"] containsString:@"GIF"];
} else if ([asset isKindOfClass:[ALAsset class]]) {
ALAsset *alAsset = asset;
_videoImageView.hidden = ![[alAsset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo];
#pragma clang diagnostic pop
_gifLable.hidden = YES;
}
}
......
......@@ -16,6 +16,7 @@
#import "TZImageManager.h"
#import "TZVideoPlayerController.h"
#import "TZPhotoPreviewController.h"
#import "TZGifPhotoPreviewController.h"
@interface ViewController ()<TZImagePickerControllerDelegate,UICollectionViewDataSource,UICollectionViewDelegate,UIActionSheetDelegate,UIImagePickerControllerDelegate,UIAlertViewDelegate,UINavigationControllerDelegate> {
NSMutableArray *_selectedPhotos;
......@@ -109,6 +110,7 @@
if (indexPath.row == _selectedPhotos.count) {
cell.imageView.image = [UIImage imageNamed:@"AlbumAddBtn.png"];
cell.deleteBtn.hidden = YES;
cell.gifLable.hidden = YES;
} else {
cell.imageView.image = _selectedPhotos[indexPath.row];
cell.asset = _selectedAssets[indexPath.row];
......@@ -138,7 +140,12 @@
ALAsset *alAsset = asset;
isVideo = [[alAsset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo];
}
if (isVideo) { // perview video / 预览视频
if ([[asset valueForKey:@"filename"] containsString:@"GIF"]) {
TZGifPhotoPreviewController *vc = [[TZGifPhotoPreviewController alloc] init];
TZAssetModel *model = [TZAssetModel modelWithAsset:asset type:TZAssetModelMediaTypePhotoGif timeLength:@""];
vc.model = model;
[self presentViewController:vc animated:YES completion:nil];
} else if (isVideo) { // perview video / 预览视频
TZVideoPlayerController *vc = [[TZVideoPlayerController alloc] init];
TZAssetModel *model = [TZAssetModel modelWithAsset:asset type:TZAssetModelMediaTypeVideo timeLength:@""];
vc.model = model;
......@@ -212,6 +219,7 @@
imagePickerVc.allowPickingVideo = self.allowPickingVideoSwitch.isOn;
imagePickerVc.allowPickingImage = self.allowPickingImageSwitch.isOn;
imagePickerVc.allowPickingOriginalPhoto = self.allowPickingOriginalPhotoSwitch.isOn;
imagePickerVc.allowPickingGif = YES;
// 4. 照片排列按修改时间升序
imagePickerVc.sortAscendingByModificationDate = self.sortAscendingSwitch.isOn;
......@@ -405,6 +413,14 @@
// _collectionView.contentSize = CGSizeMake(0, ((_selectedPhotos.count + 2) / 3 ) * (_margin + _itemWH));
}
// If user picking a gif image, this callback will be called.
// 如果用户选择了一个gif图片,下面的handle会被执行
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingGifImage:(UIImage *)animatedImage sourceAssets:(id)asset {
_selectedPhotos = [NSMutableArray arrayWithArray:@[animatedImage]];
_selectedAssets = [NSMutableArray arrayWithArray:@[asset]];
[_collectionView reloadData];
}
#pragma mark - Click Event
- (void)deleteBtnClik:(UIButton *)sender {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment