1、图片显示相关
1)、图片聊天背景拉伸不失真
2)、捏合、双击、下拉缩放
3)、Banner、相册
4)、动画
2、图片操作相关
1)、获取、下载图片(分享、传图片用)
2)、保存UIImage到本地
3)、绘制、解压图片
3-1)、用原尺寸绘制
3-2)、修改大小绘制,免得每次拿原始大图片缩放显示
4)、压缩图片
0、写在前面
1)、图片,显示模式为缩放以充满全屏,需要注意,剪切超出View的部分,否则有时有问题。
self.photoImgV.contentMode = UIViewContentModeScaleAspectFill; self.photoImgV.clipsToBounds = YES;
2)、加载网络图片,更新 imageView 尺寸。因为涉及缩放,所以要按比例算高度。
// 缩放,宽度为 SCREEN_WIDTH self.goodsDetailImgV.contentMode = UIViewContentModeScaleAspectFit; // 网图加载成功,按比例更新高度 [self.goodsDetailImgV sd_setImageWithURL:[NSURL URLWithString:data[@"pic"]] placeholderImage:[UIImage imageNamed:@"default_image"] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { [self.goodsDetailImgV mas_updateConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo( (SCREEN_WIDTH/image.size.width) * image.size.height ); }]; }];
1、图片显示相关
1)、图片聊天背景拉伸不失真
1-1)、方法1,比较老的
UIImage *originalImage = [UIImage imageNamed:@"sub.png"]; finalImage = [originalImage stretchableImageWithLeftCapWidth:originalImage.size.width/2 topCapHeight:0];
1-2)、方法2,比较新的
UIImage *originalImg = [UIImage imageNamed:@"sub"]; CGFloat protectH = originalImg.size.height/2; CGFloat protectW = originalImg.size.width/2; UIEdgeInsets protectEdg = UIEdgeInsetsMake(protectH, protectW, protectH, protectW); UIImage *finalImg = [originalImg resizableImageWithCapInsets:protectEdg resizingMode:UIImageResizingModeStretch];
后续补充:
根据情况,设置 Insets ,不一定都要取中点。意义为,分别保护 {0, 0, 0, 0} 到 {top, left, bottom, right} 距离的图片。
2)、捏合、双击、下拉缩放
2-1)、捏合缩放
1)、设置最大、最小缩放比例
scrollview.maximumZoomScale = 2.0; scrollview.minimumZoomScale = 0.5;
2)、设置代理
scrollview.delegate = self;
3)、添加上ImageView
imageView.tag = 101; [scrollview addSubview:imageView];
4)、给代理要缩放的View(不一定要添加上才可以缩放,可以缩放不在本 scrollview 的View,效果就很奇葩了)
- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { UIImageView *imageView = [scrollView viewWithTag:101]; return imageView; }
2-2)、双击缩放
0)、需要注意的地方:
0-1)、scrollView要设最大/小缩放比例!
0-2)、因为图片层在最上面,且默认不可交互,所以,图片的View记得userInteractionEnabled = YES 。
0-3)、ScrollView需要缩小尺寸,重设contentsize的时候,如删除某照片,要先清掉超出的的控件、数据。否则拉到底,弹性的时候,还能看到之前的。
1)、scrollView才可以缩放,所以要把ImageView加在scrollView,给scrollView添加手势识别。
UITapGestureRecognizer *imageTwoTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(twoTapAction:)]; imageTwoTap.numberOfTapsRequired = 2; [scrollView addGestureRecognizer: imageTwoTap];
2)、第一次点哪放大哪,第二次恢复原来大小
#define SCALE_WIDTH 60 //要放大的局部宽度大小 #define SCALE_HEIGHT 60 //要放大的局部高度大小 -(void)twoTapAction:(UITapGestureRecognizer *)tap { UIScrollView *scrollView = (UIScrollView *)tap.view; if (scrollView.zoomScale != 1.0) { [scrollView setZoomScale:1.0 animated:YES]; } else { CGPoint tapPoint = [tap locationInView:scrollView]; [scrollView zoomToRect:CGRectMake(tapPoint.x-SCALE_WIDTH/2, tapPoint.y-SCALE_HEIGHT/2, SCALE_WIDTH, SCALE_HEIGHT) animated:YES]; } }
3)、需要给代理放大、缩小的ImageView
- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { if ([[scrollView viewWithTag:1000] isMemberOfClass:[UIImageView class]]) { return [scrollView viewWithTag:1000]; } return nil; }
2-3)、下拉缩放
//根据手势位置缩放、移动view,判断所在位置需要返回,待补充
3)、Banner、相册
1)、图片移动、
4)、动画
参照《iOS:动画》 -> "0、写在前面" -> "4)、UIImageView 有自带的动画属性、方法:"
2、图片操作相关
1)、获取、下载图片(分享、传图片用)
1-1)、从 SDWebImage 缓存取
SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager diskImageExistsForURL:url completion:^(BOOL isInCache) { UIImage *img = nil; if (isInCache) { // 有,直接取 img = [[manager imageCache] imageFromDiskCacheForKey:url.absoluteString]; }else{ // 无,下载 } }];
1-2)、下载
1)、同步加载图片(仅做了解)
NSData *imgData = [NSData dataWithContentsOfURL:url]; UIImage *image = [[UIImage alloc] initWithData:imgData];
2)、异步加载图片(仅做了解)
- (void)loadImageFromWebWithURL:(NSURL*)url { dispatch_queue_t queue = dispatch_queue_create("test", NULL); dispatch_async(queue, ^{ // 获取数据 NSData *data = [NSData dataWithContentsOfURL:url]; // 主线程 dispatch_sync(dispatch_get_main_queue(), ^{ UIImage *image = [UIImage imageWithData:data]; }); }); }
3)、SDWebImageDownloader 直接下载
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader]; [downloader downloadImageWithURL:url options:SDWebImageDownloaderHighPriority progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) { // 进度 } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { // 完成 }];
2)、保存UIImage到本地
2-1)、弄成data
// UIImage 转换成 data、图片 保存 UIImage *img = [UIImage imageNamed:@"test"]; //png格式 NSData *imageData = UIImagePNGRepresentation(img); //JEPG格式 NSData *imageData = UIImageJPEGRepresentation(img,1.0);
2-2)、写入
1)、直接写入
NSString *cashesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) firstObject]; // png,data写入 [imageData writeToFile:[cashesPath stringByAppendingPathComponent:@"image1.png"] atomically:YES]; // jpg,data写入 [imageData writeToFile:[cashesPath stringByAppendingPathComponent:@"image1.jpg"] atomically:YES];
2)、用fileManage写入
NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *cashesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) firstObject]; // 将图片保存为PNG格式 [fileManager createFileAtPath:[cashesPath stringByAppendingString:@"/image2.png"] contents:imageData attributes:nil]; // 将图片保存为JPEG格式 [fileManager createFileAtPath:[cashesPath stringByAppendingString:@"/image2.jpg"] contents:imageData attributes:nil];
补充:测试后,无论 data 还是 fileManage 写入,同格式大小一致。如 image1.png 和 image2.png 。image1.jpg 和image2.jpg。
3)、绘制、解压图片
3-1)、用原尺寸绘制
UIGraphicsBeginImageContextWithOptions(image.size, YES, 0); [image drawAtPoint:CGPointZero]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
补充:意义不大,文件太大。目的是为了及时解压、刷新UI、且不改变原图片?
3-2)、修改大小绘制,免得每次拿原始大图片缩放显示
UIGraphicsBeginImageContextWithOptions(size, YES, 0); [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
补充:1、注意size的设置。
1)、如果是按原图片的size比例,最大一边为1280,绘制没问题。
2)、如果是按显示控件 UIImageView 等固定size绘制,可能会出现,图片变形以填充满size。
2、UIGraphicsBeginImageContextWithOptions(size, YES, 0) 会比 UIGraphicsBeginImageContext(size) 效果好。
4)、压缩图片
// 最大边长 #define kMaxLength 1280.0 // JPG格式压缩质量 0 - 1 #define kJPGCompressionQuality 0.5 #pragma mark - 根据宽高压缩图片 - (UIImage*)imageWithImage:(UIImage*)originalImage scaleToSize:(CGSize)finalSize{ UIGraphicsBeginImageContextWithOptions(finalSize, YES, 0); [originalImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)]; UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return finalImage; } #pragma mark - 压缩一张图片 自定义最大宽高 - (UIImage*)imageWithImage:(UIImage*)originalImage maxLength:(CGFloat)maxLength{ CGFloat originalImageW = originalImage.size.width; CGFloat originalImageH = originalImage.size.height; //宽高比 // CGFloat aspectRatio = originalImageW / originalImageH; CGFloat finalImageW = originalImageW; CGFloat finalImageH = originalImageH; if(originalImageW > maxLength || originalImageH > maxLength){ //超过设置的最大宽度 判断那个边最长 if(originalImageW > originalImageH){ //宽度大于高度 finalImageW = maxLength; finalImageH = (maxLength * originalImageH)/originalImageW; }else{ finalImageH = maxLength; finalImageW = (maxLength * originalImageW)/originalImageH; } } UIImage *finalImage = [self imageWithImage:originalImage scaleToSize:CGSizeMake(finalImageW, finalImageH)]; NSData *finalImageData = nil; if (UIImagePNGRepresentation(finalImage) == nil) { finalImageData = UIImageJPEGRepresentation(finalImage, kJPGCompressionQuality); }else{ finalImageData = UIImagePNGRepresentation(finalImage); } return [UIImage imageWithData:finalImageData]; } #pragma mark - 压缩多张图片 自定义最大宽高 - (NSArray<UIImage*>*)imageArrayWithImageArray:(NSArray<UIImage*>*)originalImageArray maxLength:(CGFloat)maxLength{ NSMutableArray *finalImageArray = [NSMutableArray array]; for (int i = 0; i<originalImageArray.count; i++) { UIImage *finalImage = [self imageWithImage:originalImageArray[i] maxLength:maxLength]; [finalImageArray addObject:finalImage]; } return finalImageArray; } #pragma mark - 压缩一张图片 最大宽或高1280 - (UIImage*)imageWithImage:(UIImage*)image{ return [self imageWithImage:image maxLength:kMaxLength]; } #pragma mark - 压缩多张图片 最大宽或高1280 - (NSArray<UIImage*>*)imageArrayWithImageArray:(NSArray<UIImage*>*)imageArr{ return [self imageArrayWithImageArray:imageArr maxLength:kMaxLength]; }
补充:
1、在方法 - (UIImage*)imageWithImage:(UIImage*)originalImage maxLength:(CGFloat)maxLength
不管尺寸是否低于设定的最大宽高,都会被绘制,可选择优化。
2、修改自《iOS-微信分享多张图片(UIActivityViewController多图分享和多图分享失败)》 -- ZFJ_张福杰 CSDN