(转)iPhone图片处理:摄像头/相册获取图片,压缩图片,上传服务器,下载,拉伸,方法总结
最近要做一个本地通讯录的App,需要上传个人头像照片,可以本地相册也可以摄像头获取,所以参考了此篇博客,很有用。
http://blog.sina.com.cn/s/blog_7e102f620101dulc.html
一、摄像头/相册获取图片,压缩图片,上传服务器,下载:
代码如下 | |
#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]; } |
我们来看看上面的从相册获取图片,我们首先要实例化UIImagePickerController对象,然后设置imagePicker对象为当前对象,设置imagePicker的图片来源为UIImagePickerControllerSourceTypePhotoLibrary,表明当前图片的来源为相册,除此之外还可以设置用户对图片是否可编辑。
代码如下 | |
#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]; } |
以上是从摄像头获取图片,和从相册获取图片只是图片来源的设置不一样,摄像头图片的来源为UIImagePickerControllerSourceTypeCamera。
在和用户交互之后,用户选择好图片后,会回调选择结束的方法。
代码如下 | |
//选择完照片后掉用的方法,可以对图片进行设置或处理 - (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info |
在回调结束的方法中,我们对图片进行了大小的处理,为图片的上传做准备。
缩放图片
代码如下 | |
//压缩图片 + (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; } |
存储图像
在上面我们获取到了图片并对图片进行了压缩,通过之前的小知识了解到,将应用需要的一些图片存入沙盒是个不错的选择,而且应用程序可以直接通过路径去方法沙盒中的图片,在这里我们将图片存入沙盒中的Documents目录下。
代码如下 | |
#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目录下获取图片
要从Documents下面获取图片,我们首先需要获取Documents目录的路径。
代码如下 | |
#pragma mark 从文档目录下获取Documents路径 - (NSString *)documentFolderPath { return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; } |
然后,我们便可以通过文件名,去访问获取资源了。
上传图片
项目中我们使用了ASIFormHttpRequest的开源框架,http请求的部分代码如下,http返回以及相关回调方法略去。
代码如下 | |
- (void)upLoadSalesBigImage:(NSString *)bigImage MidImage:(NSString *)midImage SmallImage:(NSString *)smallImage { NSURL *url = [NSURL URLWithString:UPLOAD_SERVER_URL]; ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; [request setPostValue:@"photo" forKey:@"type"]; [request setFile:bigImage forKey:@"file_pic_big"]; [request buildPostBody]; [request setDelegate:self]; [request setTimeOutSeconds:TIME_OUT_SECONDS]; [request startAsynchronous]; } |
或者不用回掉函数,用阻塞块。
NSString *strUrl = [[NSString alloc] initWithFormat:@"%@/setting.php",_HTTP_SERVER ];
NSURL *url = [NSURL URLWithString:strUrl];
strUrl = Nil;
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
NSMutableDictionary *dic = [NSMutableDictionarydictionary];
//上传图片
NSData *imageData = UIImagePNGRepresentation(headImage);
[request setData:imageData withFileName:@"temp22.png"andContentType:@"image/png" forKey:@"uploadImage"];//和服务器对应
postString = Nil;
[request setCompletionBlock:^{
//服务器成功返回
NSLog(@"request.responseString = %@",[request responseString]);NSDictionary *dic = [NSJSONSerializationJSONObjectWithData:request.responseData options:NSJSONReadingMutableContainers error:Nil];
if (dic){}
}];
[request setFailedBlock:^{
}];
[request startAsynchronous];//异步请求;
return ;
//下载图片:
+ (void) DownHeadImage:(PSHUserInfo *)friend
{
NSString *imageUrl = [NSStringstringWithFormat:@"%@/%@",_HTTP_SERVER,friend.userImageUrl];
NSLog(@"%@",imageUrl);
NSURL *url = [NSURL URLWithString:imageUrl];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setFailedBlock:^{
NSLog(@"下载失败");
}];
[request setCompletionBlock:^{
UIImage *image = [UIImage imageWithData:request.responseData];
friend.userImage = image;
}];
[request startAsynchronous];
}
二、iphone图片拉伸的几种方法:
系统至ios6之后,关于图片拉伸的方法已经扩展至3个函数:
1.ios4提供的方法:
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight
这个函数是UIImage的一个实例函数,它的功能是创建一个内容可拉伸,而边角不拉伸的图片,需要两个参数,第一个是不拉伸区域距离左边框的宽度,第二个参数是不拉伸区域距离上边框的宽度,其操作本质是对一个像素的复制拉伸,故没有渐变效果,这也是其缺点所在。
参数的意义是,如果参数指定10,5。那么,图片左边10个点,上边5个点。不会被拉伸,x坐标为11的点会被横向复制,y坐标为6的点会被纵向复制。注意:只是对一个点像素进行复制到指定的宽度。(即划出下图的椭圆部分,然后非椭圆部分拉升)
2.ios5提供的方法
- (UIImage *)resizableImageCapInsets:(UIEdgeInsets)Insets
其中Insets这个参数的格式是(top,left,bottom,right),从上、左、下、右分别在图片上画了一道线,这样就给一个图片指定了一个矩形区域。只有在框里面的部分才会被拉伸,而框外面的部分则保持改变。比如(20,5,10,5),意思是下图矩形里面的部分可以被拉伸,而其余部分不变。
3.ios6提供的方法:
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode
关于Insets参数,与ios5是相同的,不同的是其后增加了一个拉伸的模式,ios6.0的版本提供了
UIImageResizingModeTile和 UIImageResizingModeStretch两种模式,从名字就可以看出,是平铺模式和拉伸模式。平铺就是复制你Insets指定的矩形区域块来填充你所指定的图片区域(也就无渐变效果),而拉伸就是通过拉伸你Insets指定的矩形区域块来填充你 所需的图片区域(有渐变效果)。我想,相较4.0的进步你也看出来了,是明显的吧,相较于以前的,图片的resize由一个点变成了一个矩形块,这样你的所指定块的渐变效果,也是可以呈现出来的。
只是,如果你需要兼容4.0的机器的话,那么还是需用老的函数来完成对图片的resize操作的。