首页 > 技术文章 > (转)iPhone图片处理:摄像头/相册获取图片,压缩图片,上传服务器,下载,拉伸,方法总结

ranger-cc 2014-01-15 20:38 原文

最近要做一个本地通讯录的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 *image= [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) 
    {
//        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    }
    theImage = [UtilMethod imageWithImageSimple:image scaledToSize:CGSizeMake(120.0, 120.0)];//调用下面的image压缩方法
    UIImage *midImage = [UtilMethod imageWithImageSimple:image scaledToSize:CGSizeMake(210.0, 210.0)];
    UIImage *bigImage = [UtilMethod imageWithImageSimple:image scaledToSize:CGSizeMake(440.0, 440.0)];
    [theImage retain];
    [self saveImage:theImage WithName:@"salesImageSmall.jpg"];
    [self saveImage:midImage WithName:@"salesImageMid.jpg"];
    [self saveImage:bigImage WithName:@"salesImageBig.jpg"];
    
    [self dismissModalViewControllerAnimated:YES];
    [self refreshData];
    [picker release];
}

  在回调结束的方法中,我们对图片进行了大小的处理,为图片的上传做准备。

 

缩放图片 

 代码如下  
//压缩图片
+ (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 allocinitWithFormat:@"%@/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操作的。

推荐阅读