ASIFormDataRequest是ASIHttpRequest类库的重要组成部分,本文就采用ASIFormDataRequest以POST方式实现图片上传。
首先,要上传图片并不是直接将图片通过URL上传的,而是要把图片转换为二进制文件。
IOS中有两个方法能直接将图片转换为二进制
UIImage *image = [UIImage imageNamed:@"xx.png"]; NSData *data = UIImagePNGRepresentation(image); NSData *data2 = UIImageJPEGRepresentation(image,1);
就是采用如上两种方法中的一个将一个图片转换为二进制数据data,然后再将data数据上传到网络上。在这里使用一个网络请求三方库ASIFormDataRequest。
具体代码如下:
//用URL初始化请求 ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:url]; //设置代理 [request setDelegate:self]; //为上传对象添加数据 //上传后保存的名字、保存类型、表单名 [request addData:dataWithFileName:@"xx.png" andContentType:@"image/png" forKey:@"file"]; //开始,异步 [request startAsynchronous];
如上就完成了图片的上传。
//剩下部分就是服务器端的事情
………………………………
方法二:
1>IOS上传图片代码
NSString *fileName = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"]; NSString *url = @"http://……/upload.aspx"; ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:url]]; [request setPostValue:@"MyName" forkey:@"name"]; [request setFile:filename forkey:@"this_file"]; [request buildRequestHeaders]; NSLog(@"header:%@",request.requestHeaders); [request startSynchronous]; NSLog(@"responseString = %@",request.requestHeaders);
2>服务器接收处理图片代码
public partial class upload : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { HttpFileCollection MyFilecollection = Request.Files; MyFilecollection[0].SaveAs(Server.MapPath("~/ImageStore/" + MyFilecollection[0].FileName)); } }
服务器端代码采用C++编写。
方法三:
IOS通过http post上传图片、文件等
在http网络请求中,post请求没有长度的限制(因为post将数据放在body中),get是放在浏览器的地址栏中。
POST有两种方式:
1>直接将数据放在body中,用contentType来区分类型是text还是json或者别的类型,这种最简单。
2>表单的形式,通过boundary来区分放置的是哪些数据,就像一个字典,用K、V放置对象。
通过我们使用ASIHttp的第三方库里面的ASIFormDataRequest来模拟Form表单提交,提交格式Header会自动识别。
下面对比下ASIHttp与传统POST的不同之处
NSMutableURLRequest传统post用法
……这里不介绍,自行百度。
下面介绍ASIHttp方法
NSURL *url = [NSURL URLWithString:@"请求地址"]; ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; [request setPostValue:@"值1" forkey:@"参数1"]; [request setPostValue:@"值2" forkey:@"参数2"]; [request start]; NSError *error = [request error]; if(!error) { NSString *response = [request responseString]; NSLog("%@",response); }
IOS摄像头/本地相册获取图片,压缩图片,上传至服务器
iphone中,图片通常存储在4个地方(相册、应用程序包、沙盒、Internet),通过这4个源,我们就可以存储应用图片。
1>相册
用户可以通过UIImagePickerController类提供的交互对话框来从相册中选择图片。但是,相册中的图片机器路径无法直接从应用程序访问,只能通过终端用户去选择和使用相册图片。
2>应用程序包
应用程序包可能会将图像与可执行程序、Info.plist文件和其他资源一同存储。我们可以通过本地文件路径来读取这些图像并在应用程序中显示它们。
3>沙盒
借助沙盒,我们可以将图片存储到Documents、Library、tmp文件夹中。这些文件均可被应用程序读取。
4>Internet
应用程序可以通过图片的URL来访问Internet上的资源。
如上是一些小知识,来自《iphone开发秘籍(第二版)》,想了解更多,自主去查阅此书。
正题部分,从摄像头/相册获取图片、压缩图片、上传图片
1>从摄像头/相册中获取图片
由用户浏览相册并选择图片给程序使用,在这里,我们需要使用UIImagePickerController类来和用户交互。使用UIImagePickerController类和用户交互,必须要实现如下2个协议。从相册获取图片,代码如下:
- (void)pickImageFromAlbum { imagePicker = [[UIImagePickerController alloc] init]; imagePicker.delegate = self; imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; imagePicker.modalTransitionStyle = UIModalTransitionStyleCoverVertical; imagePicker.allowsEditing = YES; [self presentModalViewController:imagePicker animated:YES]; }
如上代码解释
首先实例化UIImagePickerController对象,接着设置代理。设置图片来源为UIImagePickerControllerSourceTypePhotoLibrary ,表明当前图片的来源为相册。
从摄像头获取图片,代码如下:
- (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)]; 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目录下,代码如下
- (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目录的路径。代码如下:
- (NSString *)documentFolderPath
{
return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
}
然后我们可以通过文件名,去访问获取资源了。
最后一步就是上传图片,这里使用的是ASIFormHttpRequest开源框架,代码如下:
- (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];
}
如下就是实际的例子,在UIWebView中调用IOS相册,并选择图片上传到Linux Web服务器上。
//http://blog.sina.com.cn/s/blog_5fb39f910101ajua.html#