iOS 使用AFN 进行单图和多图上传 摄像头/相册获取图片,压缩图片
图片上传时必要将图片进行压缩,不然会上传失败
首先是同系统相册选择图片和视频。iOS系统自带有UIImagePickerController,可以选择或拍摄图片视频,但是最大的问题是只支持单选,由于项目要求需要支持多选,只能自己自定义。获取系统图库的框架有两个,一个是ALAssetsLibrary,兼容iOS低版本,但是在iOS9中是不建议使用的;另一个是PHAsset,但最低要求iOS8以上。兼容到iOS7,可以选择了ALAssetsLibrary 现在我们先说选择一张图的情况
一、单图多图上传
1.单张图上传
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager POST:urlString parameters:params constructingBodyWithBlock:^(id_Nonnull formData) {
//使用日期生成图片名称
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *fileName = [NSString stringWithFormat:@"%@.png",[formatter stringFromDate:[NSDate date]]];
[formData appendPartWithFileData:imageData name:@"uploadFile" fileName:fileName mimeType:@"image/png"];
} success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
//上传图片成功执行回调
completion(responseObject,nil);
} failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
//上传图片失败执行回调
completion(nil,error);
}];
2.多图上传
多图上传和单图上传区别在于文件名称
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager POST:urlString parameters:params constructingBodyWithBlock:^(id_Nonnull formData) {
NSInteger imgCount = 0;
for (NSData *imageData in imageDatas) {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss:SSS";
NSString *fileName = [NSString stringWithFormat:@"%@%@.png",[formatter stringFromDate:[NSDate date]],@(imgCount)];
[formData appendPartWithFileData:imageData name:[NSString stringWithFormat:@"uploadFile%@",@(imgCount)] fileName:fileName mimeType:@"image/png"];
imgCount++;
}
} success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
completion(responseObject,nil);
} failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
completion(nil,error);
}];
二、获取图片,压缩图片
当从摄像头/相册获取图片 我们需要过UIImagePickerController类来和用户交互 使用UIImagePickerController和用户交互,我们需要实现2个协议<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
1.获取图片(从相册中或摄像头中)
1.1 我们首先要实例化UIImagePickerController对象,然后设置imagePicker对象为当前对象,设置imagePicker的图片来源为UIImagePickerControllerSourceTypePhotoLibrary,表明当前图片的来源为相册,除此之外还可以设置用户对图片是否可编辑
#pragma mark 从用户相册获取活动图片
- (void)pickImageFromAlbum
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
imagePicker.allowsEditing = YES;
[self presentModalViewController:imagePicker animated:YES];
}
1.2和从相册获取图片只是图片来源的设置不一样,摄像头图片的来源为UIImagePickerControllerSourceTypeCamera
#pragma mark 从摄像头获取活动图片
- (void)pickImageFromCamera
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
imagePicker.allowsEditing = YES;
[self presentModalViewController:imagePicker animated:YES];
}
1.3在和用户交互之后,用户选择好图片后,会回调选择结束的方法
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image= [info objectForKey:@"UIImagePickerControllerOriginalImage"];
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera)
{
// UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}
theImage = [UtilMethod imageWithImageSimple:image scaledToSize:CGSizeMake(120.0, 120.0)];
UIImage *midImage = [UtilMethod imageWithImageSimple:image scaledToSize:CGSizeMake(210.0, 210.0)];
UIImage *bigImage = [UtilMethod imageWithImageSimple:image scaledToSize:CGSizeMake(440.0, 440.0)];
[self saveImage:theImage WithName:@"salesImageSmall.jpg"];
[self saveImage:midImage WithName:@"salesImageMid.jpg"];
[self saveImage:bigImage WithName:@"salesImageBig.jpg"];
[self dismissModalViewControllerAnimated:YES];
[self refreshData];
}
//压缩图片(缩放图片)
+ (UIImage*)imageWithImageSimple:(UIImage*)image scaledToSize:(CGSize)newSize
{
// Create a graphics image context
UIGraphicsBeginImageContext(newSize);
// Tell the old image to draw in this new context, with the desired
// new size
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Get the new image from the context
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
// End the context
UIGraphicsEndImageContext();
// Return the new image.
return newImage;
}
// 存储图像
pragma mark 保存图片到document
- (void)saveImage:(UIImage *)tempImage WithName:(NSString *)imageName
{
NSData* imageData = UIImagePNGRepresentation(tempImage);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
// Now we get the full path to the file
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
// and then we write it out
[imageData writeToFile:fullPathToFile atomically:NO];
}
//从Documents目录下获取图片
#pragma mark 从文档目录下获取Documents路径
- (NSString *)documentFolderPath
{
return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
}
然后,我们便可以通过文件名,去访问获取资源了
补充:iOS 图片压缩处理
首先,我们必须明确图片的压缩其实是两个概念:
- “压” 是指文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降。
- “缩” 是指文件的尺寸变小,也就是像素数减少,而长宽尺寸变小,文件体积同样会减小。
图片“压”处理
对于“压”的功能,我们可以使用UIImageJPEGRepresentation或UIImagePNGRepresentation方法实现,如:
NSData *imgData = UIImageJPEGRepresentation(image, 0.5);
第一个参数是图片对象,第二个参数是压的系数,其值范围为0~1。
UIImageJPEGRepresentation方法的官方注释是:return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)
关于PNG和JPEG格式压缩
UIImageJPEGRepresentation函数需要两个参数:图片的引用和压缩系数而UIImagePNGRepresentation只需要图片引用作为参数.UIImagePNGRepresentation(UIImage \*image)要比UIImageJPEGRepresentation(UIImage* image, 1.0)返回的图片数据量大很多.
同样的一张照片, 使用UIImagePNGRepresentation(image)返回的数据量大小为199K,而 UIImageJPEGRepresentation(image, 1.0)返回的数据量大小只为140K,比前者少了59K.
如果对图片的清晰度要求不是极高,建议使用UIImageJPEGRepresentation,可以大幅度降低图片数据量.比如,刚才拍摄的图片,通过调用UIImageJPEGRepresentation(image, 1.0)读取数据时,返回的数据大小为140K,但更改压缩系数为0.5再读取数据时,返回的数据大小只有11K,大大压缩了图片的数据量,而且清晰度并没有相差多少,图片的质量并没有明显的降低。因此,在读取图片数据内容时,建议优先使用UIImageJPEGRepresentation,并可根据自己的实际使用场景,设置压缩系数,进一步降低图片数据量大小。
提示:压缩系数不宜太低,通常是0.3~0.7,过小则可能会出现黑边等。
我们看一下笔者使用UIImageJPEGRepresentation的数据表:
笔者统计了iphone设备上的全屏图和原始图在压缩前和压缩后的大小,我们需要根据图片压缩后在PC上的清晰度来决定最终选择哪个压缩系数。
图片“缩”处理
通过[sourceImage drawInRect:CGRectMake(0, 0, targetWidth, targetHeight)]可以进行图片“缩”的功能。如下是笔者对图片尺寸缩的api:
/*!
* @author 黄仪标, 15-12-01 16:12:01
*
* 压缩图片至目标尺寸
*
* @param sourceImage 源图片
* @param targetWidth 图片最终尺寸的宽
*
* @return 返回按照源图片的宽、高比例压缩至目标宽、高的图片
*/
- (UIImage *)compressImage:(UIImage *)sourceImage toTargetWidth:(CGFloat)targetWidth {
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetHeight = (targetWidth / width) * height;
UIGraphicsBeginImageContext(CGSizeMake(targetWidth, targetHeight));
[sourceImage drawInRect:CGRectMake(0, 0, targetWidth, targetHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
我们对图片只“压”而不缩,有时候是达不到我们的需求的。因此,适当地对图片“缩”一“缩“尺寸,就可以满足我们的需求。
提示:我们获取到的全屏图的宽高不是指设备的宽高,通常会比设置的宽要大,高度可能相等。我们可以拍全景图,那么宽就很大了。
iOS 使用AFN 进行单图和多图上传 摄像头/相册获取图片,压缩图片的更多相关文章
- iOS 使用AFN 进行单图和多图上传
图片上传时必要将图片进行压缩,不然会上传失败 1.单张图上传 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManag ...
- [PHP] layui实现多图上传,图片自由排序,自由删除
实现效果如下图所示: 实现代码: css代码 <style> .layui-upload-img { width: 90px; height: 90px; margin: ; } .pic ...
- layui多图上传
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 多图上传控制器及模型代码(2)thinkphp5+layui实现多图上传保存到数据库,可以实现图片自由排序,自由删除。
公共css代码 <style> .layui-upload-img { width: 90px; height: 90px; margin: 0; } .pic-more { width: ...
- thinkphp+layui多图上传(1)thinkphp5+layui实现多图上传保存到数据库,可以实现图片自由排序,自由删除。
公共css代码 <style> .layui-upload-img { width: 90px; height: 90px; margin: 0; } .pic-more { width: ...
- Laravel5多图上传和Laravel5单图上传的功能实现
Laravel5文件上传默认只能上传一张图片,但是有的时候我们需要一次性上传多图就不行了,我在网上看了很多关于laravel5图片上传的文章,很多都只是介绍laravel5单图上传,多图片上传介绍少之 ...
- iOS多图上传
iOS多图上传涉及到多线程问题,个人比较喜欢使用GCD操作,下边是最近写的一个多图上传代码,附带相关注释 __block BOOL allSucc = YES; __block int m = 0; ...
- js formData图片上传(单图上传、多图上传)后台java
单图上传 <div class="imgUp"> <label>头像单图</label> <input type=&quo ...
- thinkphp5,单图,多图,上传
/** * 上传单图 */ function upload($path, $filename) { $file = request()->file($filename); $info = $fi ...
随机推荐
- python idea 利用树莓派做家庭报警系统
1 利用树莓派做家庭报警系统idea 功能如下: 1.程序家侧人不在家(7:00-6:00) 2.树莓派搭配摄像头,对这门进行图像识别,如果变化,门开了,就报警: 3.报警的方式是给我发短信,采信,或 ...
- web编码
1各种编码 A .1 html编码 -HTML标签 this.Response.Write(this.Server.HtmlEncode("<h1>的作用将文本设置为标题样式! ...
- 【Unity笔记】UGUI的Image、RawImage控件
Image控件只能使用Sprite图片,RawImage通常使用Texture类型图片.项目设为2D模式后导入的图片Texture Type会自动转为Sprite. 没有选择源图片时,可以只选择颜色. ...
- libRTMP文档
https://rtmpdump.mplayerhq.hu/ 原文地址:http://rtmpdump.mplayerhq.hu/librtmp.3.html git clone git://git. ...
- 关于datatable导出execl
导出主要考虑响应流的问题 curContext.Response.ContentType = "application/vnd.ms-excel"; curContext.Resp ...
- LoadRunner性能测试基础知识问答
Q1:什么是负载测试?什么是性能测试? A1:负载测试是通过逐步增加系统负载,测试系统性能的变化,并最终确定在满足性能指标的情况下,系统所能承受的最大负载量的测试,例如,访问一个页面的响应时间规定不超 ...
- Android Activity 传递数据
activity中数据的传递方式有2中,一种是使用putExtra()传递,另外一种是传递Bundle对象,使用putExtras()方法. 方法一 发送数据 putExtra()传送的是键值对,第一 ...
- JAVA 多线程机制(一)
PS:又开始忙叨JAVA了..前一阵子搞定了HTML+CSS,要开始写实验室的界面了,真没劲...博客到时候再更新吧! 先更新JAVA的吧... 多线程(一) 主要内容 1.JAVA中的线程 2.用T ...
- linux -- ubuntu 何为软件源
新手学Ubuntu的时候,一般不知道什么是源,但源又是Ubuntu下常用到的东西.因此,本文就详细介绍一下Ubuntu 源. 什么是软件源? 源,在Ubuntu下,它相当于软件库,需要什么软件,只要记 ...
- oracle jar
关于oracle 11g jdbc驱动 的jar包 (2012-11-21 11:17:41)转载▼ 标签: 杂谈 分类:java学习 oracle11的jdbc\lib下没有classer12.ja ...