您不应使用UIImageJPEGRepresentation 或UIImagePNGRepresentation。那些会丢失图像的元数据,使文件变大(或者如果您选择 JPEG 压缩因子使NSData 变小,它会降低图像质量)等等。
我建议您保存UIImagePickerControllerReferenceURL,然后,当用户选择保存图像时,您返回照片框架并检索图像的底层NSData。
所以,请务必导入 Photos 框架:
@import Photos;
另外,定义一个属性来捕获 URL:
@property (nonatomic, strong) NSURL *imageReferenceURL;
然后在获取图片的时候捕获这个URL:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
self.imageReferenceURL = info[UIImagePickerControllerReferenceURL];
[picker dismissViewControllerAnimated:YES completion:nil];
}
当你去上传图片时,从照片框架中检索原始资产的NSData:
- (IBAction)uploadPic:(UIButton *)sender {
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[self.imageReferenceURL] options:nil];
PHAsset *asset = [result firstObject];
if (asset) {
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
// insert your code for uploading here, referencing the `imageData` here rather than `dataImage`.
// Or, I might recommend AFNetworking:
//
// For example, if your web service was expecting a `multipart/form-data` POST and was
// going to return a JSON response, you could do something like:
NSString *urlString = @"http://192.168.0.10/udazz/2.0/2.2/ios/1.0/actions.php?targ=user&subTarg=post&txtComment=123456&txtType=ff";
NSDictionary *parameters = @{@"targ" : @"user",
@"subTarg" : @"post",
@"txtComment" : @"123456",
@"txtType" : @"ff"};
NSURL *fileURL = info[@"PHImageFileURLKey"];
NSString *filename = [fileURL lastPathComponent];
NSString *mimeType = [self mimeTypeForPath:filename];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // if response is string rather than JSON, uncomment this line
[manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:@"userfile" fileName:filename mimeType:mimeType];
} success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"responseObject = %@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"error = %@", error);
}];
}];
}
}
或者,如果您想使用自己的上传代码,只需将其调整为使用 NSURLSession(因为 NSURLConnection 现在已弃用,无论如何您都不应该进行同步网络请求):
- (IBAction)uploadPic:(UIButton *)sender {
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[self.imageReferenceURL] options:nil];
PHAsset *asset = [result firstObject];
if (asset) {
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
// upload the `imageData`
NSURL *fileURL = info[@"PHImageFileURLKey"];
NSString *filename = [fileURL lastPathComponent];
NSString *mimeType = [self mimeTypeForPath:filename];
NSString *urlString = @"http://192.168.0.10/udazz/2.0/2.2/ios/1.0/actions.php?targ=user&subTarg=post&txtComment=123456&txtType=ff";
NSMutableURLRequest* request= [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:imageData];
[postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:postbody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Response %@",responseString);
}];
[task resume];
}];
}
}
顺便说一下,我以编程方式确定 mime 类型的例程(因为你真的不能只假设图像是 JPEG;它也可能是 PNG 和其他类型)如下:
- (NSString *)mimeTypeForPath:(NSString *)path {
// get a mime type for an extension using MobileCoreServices.framework
CFStringRef extension = (__bridge CFStringRef)[path pathExtension];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL);
assert(UTI != NULL);
NSString *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType));
assert(mimetype != NULL);
CFRelease(UTI);
return mimetype;
}
如果您需要支持早于 Photos 框架的 iOS 版本,请使用ALAssetsLibrary 获取NSData。如果您需要如何执行此操作的示例(仅当您需要支持 8.0 之前的 iOS 版本时),请告诉我。