1. 將圖片轉(zhuǎn)換為Base64編碼想邦,POST上傳裤纹。PHP將Base64解碼為二進(jìn)制,再寫出文件案狠。
缺點:不能上傳較大的圖片
原因:post 理論上講是沒有大小限制的服傍,HTTP協(xié)議規(guī)范也沒有進(jìn)行大小限制,但實際上post所能傳遞的數(shù)據(jù)量大小取決于服務(wù)器的設(shè)置和內(nèi)存大小骂铁。以php語言來說吹零,上傳文件最大是默認(rèn)是2MB,更改這個值需要更改php.conf的post_max_size這個值拉庵。
// iOS(Swift)
func upload(image: UIImage, url: String) {
let imageData = UIImageJPEGRepresentation(image, 0.3) // 將圖片轉(zhuǎn)換成jpeg格式的NSData灿椅,壓縮到0.3
let imageStr = imageData?.base64EncodedStringWithOptions(.Encoding64CharacterLineLength) // 將圖片轉(zhuǎn)換為base64字符串
let params: NSDictionary = ["file": imageStr!]
let manager = AFHTTPRequestOperationManager()
// 采用POST的方式上傳,因為POST對長度沒有限制
manager.POST(url, parameters: params, success: { (_: AFHTTPRequestOperation!, response: AnyObject!) in
// 成功
}) { (_: AFHTTPRequestOperation!, _: NSError!) in
// 失敗
}
}
<?php
header('Content-type: text/json; charset=UTF-8');
$base64 = $_POST["file"]; // 得到參數(shù)
$img = base64_decode($base64); // 將格式為base64的字符串解碼
$path = "md5(uniqid(rand()))".".jpg"; // 產(chǎn)生隨機(jī)唯一的名字作為文件名
file_put_contents($path, $img); // 將圖片保存到相應(yīng)位置
?>
2.AFNetworking上傳钞支,PHP端通過正常接收網(wǎng)頁上傳方法來接收圖片
static func uploadPortrait(image: UIImage, url: String) {
let manager = AFHTTPRequestOperationManager()
// fromData: AFN封裝好的http header類茫蛹,可以添加請求體
manager.POST(url, parameters: [:], constructingBodyWithBlock: { (fromData: AFMultipartFormData!) in
let pngData = UIImagePNGRepresentation(image)
// name必須和后臺PHP接收的參數(shù)名相同($_FILES["file"])
// fileName為圖片名
fromData.appendPartWithFileData(pngData, name: "file", fileName: "image.png", mimeType: "image/png")
// let jpegData = UIImageJPEGRepresentation(image, 0.3)
// fromData.appendPartWithFileData(jpegData, name: "file", fileName: "image.jpg", mimeType: "image/jpeg")
}, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) in
// 成功
}) { (operation: AFHTTPRequestOperation!, error: NSError!) in
// 失敗
}
}
<?php
header('Content-type: text/json; charset=UTF-8' );
/**
* $_FILES 文件上傳變量,是一個二維數(shù)組烁挟,第一維保存上傳的文件的數(shù)組婴洼,第二維保存文件的屬性,包括類型撼嗓、大小等
* 要實現(xiàn)上傳文件柬采,必須修改權(quán)限為加入可寫 chmod -R 777 目標(biāo)目錄
*/
// 文件類型限制
// "file"名字必須和iOS客戶端上傳的name一致
if (($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/png")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
// && ($_FILES["file"]["size"] < 20000)) // 小于20k
{
if ($_FILES["file"]["error"] > 0) {
echo $_FILES["file"]["error"]; // 錯誤代碼
} else {
$fillname = $_FILES['file']['name']; // 得到文件全名
$dotArray = explode('.', $fillname); // 以.分割字符串,得到數(shù)組
$type = end($dotArray); // 得到最后一個元素:文件后綴
$path = "../portrait/".md5(uniqid(rand())).'.'.$type; // 產(chǎn)生隨機(jī)唯一的名字
move_uploaded_file( // 從臨時目錄復(fù)制到目標(biāo)目錄
$_FILES["file"]["tmp_name"], // 存儲在服務(wù)器的文件的臨時副本的名稱
$path);
echo "成功";
}
} else {
echo "文件類型不正確";
}
?>
3.將圖片封裝在Http的請求報文中的請求體(body)中上傳且警。也是AFN上傳的原理
// 使用OC封裝
#import <UIKit/UIKit.h>
@interface RequestPostUploadHelper : NSObject
+ (NSMutableURLRequest *)uploadImage:(NSString*)url uploadImage:(UIImage *)uploadImage params:(NSMutableDictionary *)params;
@end
#import "RequestPostUploadHelper.h"
@implementation RequestPostUploadHelper
+ (NSMutableURLRequest *)uploadImage:(NSString*)url uploadImage:(UIImage *)uploadImage params:(NSMutableDictionary *)params {
[params setObject:uploadImage forKey:@"file"];
//分界線的標(biāo)識符
NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
//根據(jù)url初始化request
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:10];
//分界線 --AaB03x
NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
//結(jié)束符 AaB03x--
NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
//要上傳的圖片
UIImage *image=[params objectForKey:@"file"];
//得到圖片的data
NSData* data = UIImagePNGRepresentation(image);
//http body的字符串
NSMutableString *body=[[NSMutableString alloc]init];
//參數(shù)的集合的所有key的集合
NSArray *keys= [params allKeys];
//遍歷keys
for(int i = 0; i < [keys count]; i++)
{
//得到當(dāng)前key
NSString *key = [keys objectAtIndex:i];
//如果key不是file粉捻,說明value是字符類型,比如name
if(![key isEqualToString:@"file"])
{
//添加分界線斑芜,換行
[body appendFormat:@"%@\r\n",MPboundary];
//添加字段名稱肩刃,換2行
[body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
//添加字段的值
[body appendFormat:@"%@\r\n",[params objectForKey:key]];
}
}
////添加分界線,換行
[body appendFormat:@"%@\r\n",MPboundary];
//聲明file字段,文件名為image.png
[body appendFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"image.png\"\r\n"];
//聲明上傳文件的格式
[body appendFormat:@"Content-Type: image/png\r\n\r\n"];
//聲明結(jié)束符:--AaB03x--
NSString *end=[[NSString alloc] initWithFormat:@"\r\n%@",endMPboundary];
//聲明myRequestData盈包,用來放入http body
NSMutableData *myRequestData = [NSMutableData data];
//將body字符串轉(zhuǎn)化為UTF8格式的二進(jìn)制
[myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
//將image的data加入
[myRequestData appendData:data];
//加入結(jié)束符--AaB03x--
[myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
//設(shè)置HTTPHeader中Content-Type的值
NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
//設(shè)置HTTPHeader
[request setValue:content forHTTPHeaderField:@"Content-Type"];
//設(shè)置Content-Length
[request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"];
//設(shè)置http body
[request setHTTPBody:myRequestData];
//http method
[request setHTTPMethod:@"POST"];
return request;
}
@end
// 使用
// Swift
static func uploadPortrait(image: UIImage, url:String) {
// 使用
let request = RequestPostUploadHelper.uploadImage(url, uploadImage: image, params: [:])
// 異步網(wǎng)絡(luò)請求
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in
if error != nil {
// 失敗
} else {
// 成功
}
}
}
<?php
// PHP代碼和上一步相同
?>
4.iOS圖片轉(zhuǎn)換為NSData沸呐,通過POST上傳。PHP接收POST參數(shù)续语,將NSData的16進(jìn)制編碼轉(zhuǎn)換為PHP支持的二進(jìn)制垂谢,再寫出文件保存
暫時沒有找到辦法,PHP接收到16進(jìn)制編碼后疮茄,
使用算法
轉(zhuǎn)換為二進(jìn)制后無法輸出圖片滥朱。在這里拋磚引玉,如果有同學(xué)知道解決辦法力试,希望簡信或者評論徙邻。
5.二進(jìn)制POST上傳。PHP直接將數(shù)據(jù)保存為圖片
暫時沒有找到辦法畸裳,iOS端使用NSData的getBytes無法轉(zhuǎn)換為二進(jìn)制缰犁。在這里拋磚引玉,如果有同學(xué)知道解決辦法怖糊,希望簡信或者評論帅容。