SwiftとPHP間の画像のやりとり
- Swiftから画像をサーバサイド(PHP)に送信
- PHPでは送られてきたデータをDBに保存
- PHPでDBに保存されたデータを取り出して、Swift側に送信
- Swift側ではPHPからの画像データを受け取って、UIImageViewに表示
画像のやりとりの勉強を兼ねて以上のような機能をもつ簡単なアプリの作成をしてます。
そこで幾つか問題が発生していて非常に困っています。
まず1→2なのですが、
SwiftからPHPではマルチパートのデータとしてPHP側に指定のURLで送信しています。
func uploadBtn(sender :UIButton){
//POSTする画像を生成
let sampleImage = UIImage(named: "images.jpg")
let imageData:NSData = NSData(data:UIImageJPEGRepresentation(sampleImage!, 1.0)!)
//NSURLRequestを生成
let url = NSURL(string: "http://192.168.33.10/test_app/images/postImage")
let urlRequest : NSMutableURLRequest = NSMutableURLRequest()
if let u = url{
urlRequest.URL = u
urlRequest.HTTPMethod = "POST"
urlRequest.timeoutInterval = 30.0
}
//BODYを作成
let uniqueId = NSProcessInfo.processInfo().globallyUniqueString
let body: NSMutableData = NSMutableData()
var postData :String = String()
let boundary:String = "---------------------------\(uniqueId)"
urlRequest.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") //(1)
postData += "--\(boundary)\r\n"
postData += "Content-Disposition: form-data; name=\"image\"; filename=\"images.jpg\"\r\n" //(2)
postData += "Content-Type: image/jpeg\r\n\r\n"
body.appendData(postData.dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData)
postData = String()
postData += "\r\n"
postData += "\r\n--\(boundary)--\r\n"
body.appendData(postData.dataUsingEncoding(NSUTF8StringEncoding)!) //(3)
urlRequest.HTTPBody = NSData(data:body)
//print(urlRequest)
//リクエストを送信してレスポンスを受け取る
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let task: NSURLSessionDataTask = session.dataTaskWithRequest(urlRequest, completionHandler: { data, request, error in
//サーバサイドから返ってきたデータ
let result = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print("result=\(result)")
})
task.resume()
}
PHPでは
public function postImage(){
if($_SERVER['REQUEST_METHOD'] == "POST"){
$data = $_FILES['image'];
/* 出力結果:
array(5) {
["name"]=>
string(10) "images.jpg"
["type"]=>
string(10) "image/jpeg"
["tmp_name"]=>
string(14) "/tmp/phpWMcdjb"
["error"]=>
int(0)
["size"]=>
int(28051)
}
*/
$db = mysql_connect('localhost','root','password');
$table = mysql_select_db('test_db');
$img = $_FILES['image']['tmp_name'];
$cont = file_get_contents($img)
if($cont){
//画像(バイナリデータ)を16進数に変換
$img_binary = bin2hex($cont);
if($table = mysql_query("insert into images (img_field) values ( ' ".$img_binary." ' )",$db)){
//echo "画像をデータベースに保存しました。\n";
$resp = true;
}else{
//echo "保存できませんでした。\n";
echo "ERROR:".mysql_error()."\n";
$resp = false;
}
}
//json形式でviewに吐く
$this->set(compact('resp'));
$this->viewClass = 'Json';
$this->set('_serialize', array('resp'));
}else{
echo "not post";
}
}
imagesテーブルのimg_fieldにfile_get_contents()で読み込んだパスの内容($cont)を16進数に変換したデータ(バイナリデータままではなぜかDBに保存できなかったため16進数に変換)が保存されていることは確認しました。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
2→3における
16進数に変換した画像データ( $cont)をDBに保存し、それらJSONに埋め込んでをPHPからSwiftに送る部分は以下のようになっています。
public function recieveImage(){
if($_SERVER['REQUEST_METHOD'] == "GET"){
$db = mysql_connect('localhost','root','imagine');
$table = mysql_select_db('test_db');
$table = mysql_query("select img_field from images",$db);
$array = $this->User->MMArray($table);
var_dump($array);
/*
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
["img_field"]=>
string(16) " /tmp/phpz3Xoy2 "
}
}
}
*/
$img = $array[0][0]["img_field"]; //$imgで16進数のデータを取得
$resp = $img;
//json形式でviewに吐く
$this->set(compact('resp'));
$this->viewClass = 'Json';
$this->set('_serialize', array('resp'));
}else{
echo "not get";
}
}
Swift側では以下のようにしてJSONを受け取っています。
func downloadBtn(sender :UIButton){
//create url request
//set URL
let urlstr = "http://192.168.33.10/test_app/images/recieveImage"
let request = NSMutableURLRequest(URL: NSURL(string: urlstr)!)
//set method
request.HTTPMethod = "GET"
//タスクの生成
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler:{ data, response, error in
//succeed post
if(error == nil){
let json = JSON(data: data!)
print("json=\(json)")
/*
json={
"resp" : " 16進数に変換された画像データ "
}
*/
}else{
print(error)
}
})
task.resume()
}
Q:得られた16進数の画像データをSwiftで表示することができません。
16進数を本来の画像(バイナリ)データに変換し、それらを表示すればよいのではないかと思っているのですが...