最近在做一个多张图片上传及图片展示功能,在这期间,碰到了几个坑,现在已经解决了,为了避免各位再走类似的坑,我将这些问题总结成一篇文章 主要包括调用图片上传,裁剪图片,图片压缩,处理图片失真等问题 希望能帮到大家:
下面是相应代码:
<1> 点击按钮(自定义) 打开相册 裁剪图片
-(void)picureUpload:(UIButton *)sender{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
//1.指定使用照相机模式,可以指定使用相册/照片库
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//2.设置相机支持的类型,拍照和录像
picker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:picker.sourceType];
//设置当拍照完或在相册选完照片后,是否跳到编辑模式 进行图片剪裁。 只有当showsCameraControls属性为true时才有效果
picker.allowsEditing = YES;
//设置拍照时的下方的工具栏是否显示,如果需要自定义拍摄界面,则可把该工具栏隐藏
// picker.showsCameraControls = YES;
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
<2> 上传图片 协议与代理方法
压缩图片 已经封装好方法 写成了一个单例 只需要把图片传过去就好
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
//获取图片的url
NSURL *imageAssetUrl = info[@"UIImagePickerControllerReferenceURL"];
//获取图片裁剪的图
UIImage* edit_image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
NSString *ext = imageAssetUrl.absoluteString;
NSLog(@"imageAssetUrl ----%@",imageAssetUrl);
NSLog(@"ext ----%@",ext);
//ext = ext substringFromIndex:
NSRange range = [ext rangeOfString:@"ext="];
ext = [ext substringFromIndex:(range.location + range.length)];
NSLog(@"新ext ----%@",ext);
int count = self.photoURLArrayM.count;
NSString *dir = NSHomeDirectory();
NSString *filePath = [NSString stringWithFormat:@"%@/Documents/images%d.%@",dir,count+1,@"png" ];
NSLog(@"dir ----%@",dir);
NSLog(@"filePath ----%@",filePath);
// UIImage *image = edit_image;
/***** 压缩图片 已经封装好方法 写成了一个单例 只需要把图片传过去就好*****/
NSData *imageData = [[LSCompressPicBase SharedInstance] needCompressPic:edit_image];
NSFileManager * fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:filePath contents:imageData attributes:nil];
if ([fileManager fileExistsAtPath:filePath]){
//取得NSURL
NSURL *imageURL = [NSURL fileURLWithPath:filePath];
NSData *data = [[NSData alloc]initWithContentsOfURL:imageURL];
UIImage *image = [[UIImage alloc] initWithData:data];
[self.photoURLArrayM addObject:imageURL];//photoURLArrayM为上传图片数组
NSLog(@"imageURL:%@",imageURL.absoluteString);
}
//选取完图片之后关闭视图
[self dismissViewControllerAnimated:YES completion:nil];
}
<3>代理方法 模态方式退出uiimagepickercontroller
- ( void )imagePickerControllerDidCancel:( UIImagePickerController *)picker
{
//模态方式退出uiimagepickercontroller
[self dismissViewControllerAnimated:YES completion:nil];
}
<4>压缩图片 及处理图片失真问题 单例
.h文件
#import@interface LSCompressPicBase : NSObject
+(_Nonnull instancetype)SharedInstance;
- (UIImage *)scaleToSizeWithImg:(UIImage *)img size:(CGSize)size;
-(NSData *)needCompressPic:(UIImage *)image;
@end
.m文件
#import "LSCompressPicBase.h"
@implementation LSCompressPicBase
+(instancetype)SharedInstance
{
static LSCompressPicBase *_instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
//压缩图片
- (UIImage *)scaleToSizeWithImg:(UIImage *)img size:(CGSize)size{
// 创建一个bitmap的context
// 并把它设置成为当前正在使用的context
//下面这个方法 上传图片会失真
// UIGraphicsBeginImageContext(size);
// 解决失真的方法 下面方法,第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。第三个参数就是屏幕密度了
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale *0.92 );//可以乘0到1 值越大 图片越清晰 不过上传的文件越大 越慢
NSLog(@"屏幕密度----%f",[UIScreen mainScreen].scale );
// 绘制改变大小的图片
[img drawInRect:CGRectMake(0,0, size.width, size.height)];
// 从当前context中创建一个改变大小后的图片
UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
// 使当前的context出堆栈
UIGraphicsEndImageContext();
//返回新的改变大小后的图片
return scaledImage;
}
//压缩图片 返回NSData数据
-(NSData *)needCompressPic:(UIImage *)image{
CGFloat fixelW = CGImageGetWidth(image.CGImage);
CGFloat fixelH = CGImageGetHeight(image.CGImage);
NSData *imageData = UIImagePNGRepresentation(image);
int length = [imageData length]/1000;
NSLog(@"压缩之前的大小 大小----%d 宽----%f 高---%f",length,fixelW,fixelH);
UIImage *imageNew;
if (length >=10000) {
imageNew = [self scaleToSizeWithImg:image size:CGSizeMake(fixelW/14.0, fixelH/14.0)];
NSLog(@"length-------fixelW/14.0---%f--fixelH/14.0---%f,压缩的倍数是14",fixelW/14.0,fixelH/14.0);
}else if (length >= 4000 && length < 10000){
imageNew = [self scaleToSizeWithImg:image size:CGSizeMake(fixelW/9.0, fixelH/9.0)];
NSLog(@"length-------fixelW/9.0---%f--fixelH/9.0---%f,压缩的倍数是9",fixelW/9.0,fixelH/9.0);
}else{
imageNew = [self scaleToSizeWithImg:image size:CGSizeMake(fixelW/6.5, fixelH/6.5)];
NSLog(@"length-------fixelW/6.5---%f--fixelH/6.5---%f,压缩的倍数是6.5",fixelW/6.5,fixelH/6.5);
}
NSData *imageData2 = UIImagePNGRepresentation(imageNew);
CGFloat fixelW2 = CGImageGetWidth(imageNew.CGImage);
CGFloat fixelH2 = CGImageGetHeight(imageNew.CGImage);
int length2 = [imageData2 length]/1000;
NSLog(@"压缩之后图片信息 大小:%dKB w:%f h:%f",length2,fixelW2,fixelH2);
return imageData2;
}
@end
<5>使用AFN上传 图片是使用文件类型上传的
上传方法中 先遍历 写在文件字典里面
AFN调用的方法