17660


  1. Swiftから画像をサーバサイド(PHP)に送信
  2. PHPでは送られてきたデータをDBに保存
  3. PHPでDBに保存されたデータを取り出して、Swift側に送信
  4. Swift側ではPHPからの画像データを受け取って、UIImageViewに表示

画像のやりとりの勉強を兼ねて以上のような機能をもつ簡単なアプリの作成をしてます。  
そこで幾つか問題が発生していて非常に困っています。

まず1→2なのですが、  
SwiftからPHPではマルチパートのデータとしてPHP側に指定のURLで送信しています。

[code]

    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()
    }
    
[/code]

PHPでは

[code]

    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";
        }
      }
    
[/code]

imagesテーブルのimg_fieldにfile_get_contents()で読み込んだパスの内容($cont)を16進数に変換したデータ(バイナリデータままではなぜかDBに保存できなかったため16進数に変換)が保存されていることは確認しました。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

2→3における  
16進数に変換した画像データ（ $cont）をDBに保存し、それらJSONに埋め込んでをPHPからSwiftに送る部分は以下のようになっています。

[code]

    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";
        }
      }
    
[/code]

Swift側では以下のようにしてJSONを受け取っています。

[code]

     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()
    }
    
[/code]

Q:得られた16進数の画像データをSwiftで表示することができません。  
16進数を本来の画像(バイナリ)データに変換し、それらを表示すればよいのではないかと思っているのですが...


CC BY-SA 3.0
2015-10-14T17:19:23.647
17657
2015-10-15T07:35:07.757
2015-10-15T07:35:07.757
12470
12470
question
swift php cakephp json
SwiftとPHP間の画像のやりとり


アップロードされた画像ファイルは $_FILES['image']['tmp_name'] に入っているpathにファイルとして保存されています。  
このファイルの内容をDBへ保存してください。

質問記載の場合、 /tmp/phpWMcdjb がアップロードされたファイル本体です。このファイルを読み込み、読み込んだ内容をDBへ保存してください。


CC BY-SA 3.0
2015-10-15T01:26:24.223
17660
2015-10-15T05:42:35.747
2015-10-15T05:42:35.747
7343
7343
17657
answer