iOS 相机拍照、相册获取照片(仿微信) 一一 从相册获取图片、图片裁剪
2017-06-10 11:42
696 查看
上篇写了使用相机拍照并裁剪的过程,本来准备把相册处理也放进去的,但考虑到放一起篇幅太长,所以还是分开来写。
上篇相机拍照的地址:http://blog.csdn.net/a44496913/article/details/72934955注:由于项目最低支持是iOS 8.0,所以我直接使用的 Photos 框架
下面进入正题
导入框架
#import <Photos/Photos.h>
获取所有的相册
- (void)getOriginalImages { // 获得所有的自定义相簿 PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; // 遍历所有的自定义相簿 for (PHAssetCollection *assetCollection in assetCollections) { [self enumerateAssetsInAssetCollection:assetCollection original:YES]; } // 获得相机胶卷 PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject; // 遍历相机胶卷,获取大图 [self enumerateAssetsInAssetCollection:cameraRoll original:YES]; }
得到相册后进行遍历,获取每个相册中所有的 PHAsset,PHAsset中包含图片和图片的信息
/** * 遍历相簿中的所有图片 * @param assetCollection 相簿 * @param original 是否要原图 */ - (void)enumerateAssetsInAssetCollection:(PHAssetCollection *)assetCollection original:(BOOL)original { NSLog(@"相簿名:%@", assetCollection.localizedTitle); // 获得某个相簿中的所有PHAsset对象 PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil]; /* 这里是把 asset 直接作为数据源添加到数组中,没有进一步的转化为图片,原因有两点: 1.转化为图片很耗时,用户体验不好 2.直接转化图片内存占用很大,一开始我直接转化为高清图,结果内存暴增闪退了 */ for (PHAsset *asset in assets) { [self.dataSource addObject:asset]; } //添加显示列表 [self.view addSubview:self.collectionView]; }
在collectionVIew 代理方法中逐个获取预览图(预览图较小,对内存压力不大)
PHAsset *asset = self.dataSource[indexPath.row]; PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; // 同步获得图片, 只会返回1张图片 options.synchronous = YES; //尺寸为零,获取的是预览图 CGSize size = CGSizeZero; // 从asset中获得图片 [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) { [cell updateCollectionViewCellInformationWithData:result]; }];
如果需要获取原图,需要修改上面方法的 size
CGSize size = CGSizeMake(asset.pixelWidth, asset.pixelHeight);
在得到原图之后就可以对其进行裁剪操作了,裁剪的处理过程和上篇的拍照裁剪类似,只是这里给图片添加了移动和缩放,所以裁剪会麻烦些,不过只要计算出裁剪比例和位置,剩下的就好处理了
/** 用于裁剪的原始图片 */ @property (strong, nonatomic) UIImage *image;
/** 图片显示 */ @property (strong, nonatomic) UIImageView *imageV; /** 图片加载后的初始位置 */ @property (assign, nonatomic) CGRect norRect; /** 裁剪框frame */ @property (assign, nonatomic) CGRect showRect; /** 用于判断是否是放大操作 */ @property (assign, nonatomic) CGFloat lastImageW;
图片移动,根据位置使其回弹
- (void)panGR:(UIPanGestureRecognizer *)sender{ CGPoint point = [sender translationInView:self.view]; _imageV.center = CGPointMake(_imageV.centerX + point.x, _imageV.centerY + point.y); [sender setTranslation:CGPointZero inView:self.view]; //手势结束,调整 imageView 位置 if (sender.state == UIGestureRecognizerStateEnded) { if (_imageV.origin.x > _showRect.origin.x || _imageV.origin.y > _showRect.origin.y || _imageV.origin.x + _imageV.size.width < _showRect.origin.x + _showRect.size.width || _imageV.origin.y + _imageV.size.height < _showRect.origin.y + _showRect.size.height) { CGRect newRect = _imageV.frame; if (_imageV.origin.x > _showRect.origin.x) { newRect.origin.x = _showRect.origin.x; } if (_imageV.origin.y > _showRect.origin.y && _imageV.frame.size.height > _showRect.size.height) { newRect.origin.y = _showRect.origin.y; } else if (_imageV.origin.y > _showRect.origin.y && _imageV.frame.size.height <= _showRect.size.height) { newRect.origin.y = (SCREEN_HEIGHT - _imageV.frame.size.height) / 2.0; } if ((_imageV.origin.x + _imageV.size.width < _showRect.origin.x + _showRect.size.width) ) { newRect.origin.x += _showRect.origin.x + _showRect.size.width - (_imageV.origin.x + _imageV.size.width); } if ((_imageV.origin.y + _imageV.size.height < _showRect.origin.y + _showRect.size.height) && (_imageV.frame.size.height > _showRect.size.height)) { newRect.origin.y += _showRect.origin.y + _showRect.size.height - (_imageV.origin.y + _imageV.size.height); } else if ((_imageV.origin.y + _imageV.size.height < _showRect.origin.y + _showRect.size.height) && (_imageV.frame.size.height <= _showRect.size.height)) { newRect.origin.y = (SCREEN_HEIGHT - _imageV.frame.size.height) / 2.0; } [UIView animateWithDuration:0.3f animations:^{ _imageV.frame = newRect; }]; } } }
缩放手势
- (void)pinGR:(UIPinchGestureRecognizer *)sender{ _imageV.transform = CGAffineTransformScale(_imageV.transform, sender.scale, sender.scale); //缩放结束,调整 imageView 位置 if (sender.state == UIGestureRecognizerStateEnded) { CGRect newRect = _imageV.frame; if (_imageV.frame.size.width <= _showRect.size.width) { CGFloat ret = _image.size.height / _image.size.width; newRect.size.width = _showRect.size.width; newRect.size.height = _showRect.size.width * ret; newRect.origin.x = _showRect.origin.x; newRect.origin.y = (SCREEN_HEIGHT - newRect.size.height) / 2.0; }else{ if (newRect.size.width < _lastImageW){ if (_imageV.centerX <= _showRect.origin.x + _showRect.size.width / 2.0) { newRect.origin.x = _showRect.origin.x + _showRect.size.width - newRect.size.width; }else{ newRect.origin.x = _showRect.origin.x; } if (_imageV.centerY <= _showRect.origin.y + _showRect.size.height / 2.0) { newRect.origin.y = _showRect.origin.y + _showRect.size.height - newRect.size.height; }else{ newRect.origin.y = _showRect.origin.y; } } } [UIView animateWithDuration:0.3f animations:^{ _imageV.frame = newRect; }]; _lastImageW = newRect.size.width; } sender.scale = 1.0; }
计算裁剪区域并裁剪
- (void)rightButtonClicked{ CGRect clipRect = CGRectZero; CGFloat h = 0; CGFloat w = 0; CGFloat originX = 0; CGFloat originY = 0; CGFloat clipW = 0; CGFloat clipH = 0; if (_imageV.size.width <= _showRect.size.width) { //图片没有放大 if (_imageV.size.height <= _showRect.size.height) //图片高度小于等于裁剪框高度,按图片高度截取正方形 { h = _imageV.size.height; w = h; originX = (_imageV.size.width - w) / 2.0 / _imageV.size.width * _image.size.width; originY = 0; } else{ //图片高度大于裁剪框高度,按裁剪框截取 h = _showRect.size.width; w = _showRect.size.width; originX = 0; originY = (_showRect.origin.y - _imageV.frame.origin.y) / _imageV.size.height * _image.size.height; } }else{ //图片被放大 if (_imageV.size.height <= _showRect.size.height) { //图片高度小于等于裁剪框高度,按图片高度截取正方形 h = _imageV.size.height; w = h; originX = (_showRect.origin.x - _imageV.frame.origin.x + (_showRect.size.width - w) / 2.0) / _imageV.size.width * _image.size.width; originY = 0; } else{ //图片高度大于裁剪框高度,按裁剪框截取 h = _showRect.size.width; w = _showRect.size.width; originX = (_showRect.origin.x - _imageV.frame.origin.x) / _imageV.frame.size.width * _image.size.width; originY = (_showRect.origin.y - _imageV.frame.origin.y) / _imageV.frame.size.height * _image.size.height; } } clipW = w / _imageV.size.width * _image.size.width; clipH = h / _imageV.size.height * _image.size.height; clipRect = CGRectMake(originX, originY, clipW, clipH); //裁剪后得到的图片 UIImage *image = [self imageFromImage:self.image inRect:clipRect]; //裁剪完成回调 if (self.pictureSelectedBlock) { self.pictureSelectedBlock(); } [_imageV removeFromSuperview]; [self dismissViewControllerAnimated:YES completion:^{ [[NSNotificationCenter defaultCenter] postNotificationName:@"PicutreFromAlbum" object:nil userInfo:@{@"image":image}]; }]; }
//裁剪方法 - (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect{ //将UIImage转换成CGImageRef CGImageRef sourceImageRef = [image CGImage]; //按照给定的矩形区域进行剪裁 CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect); //将CGImageRef转换成UIImage UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; //返回剪裁后的图片 return newImage; }
Demo地址:https://github.com/HuberyYang/CameraDemo.git
相关文章推荐
- iOS 相机拍照、相册获取照片(仿微信) 一一 拍照、图片裁剪
- android 调用系统相册选取照片或者打开相机拍照获取图片
- 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
- iOS 调用相机 ,相册获取图片 并裁剪为正方形
- iOS从相机或相册获取图片并裁剪,再获取裁剪后的图片
- 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
- 一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库
- iOS拍照后使用该图片(获取照片的ALasset传到相册)
- iOS 从相机或相册获取图片并裁剪
- iOS 从相机或相册获取图片并裁剪
- [转]微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
- TakePhoto是一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库,目前最新版本3.0.0。
- 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
- android 调用系统相册选取照片或者打开相机拍照获取图片,返回时回到手机桌面,然后才会跳转到当前activity
- 微信小程序-从相册获取图片,视频 使用相机拍照,录像上传+服务器(nodejs版)接收
- iOS 从相机或相册获取图片并裁剪
- 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
- iOS 从相机或相册获取图片并裁剪
- iOS开发 使用UIImagePicker从相机或相册获取图片并裁剪
- iOS 从相机或相册获取图片并裁剪