Swift 2,将Base64图像上传至PHP

3

我在尝试将图片上传到PHP时遇到了巨大的问题。

我的脚本正常工作,但当我在线查看图像时,它显示为损坏的图像。如果我下载它并尝试在Photoshop中打开,它会说图像已损坏。

Swift文件上传脚本

func percentEscapeString(string: String) -> String {
    return CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
        string,
        nil,
        ":/?@!$&'()*+,;=",
        CFStringBuiltInEncodings.UTF8.rawValue) as String;
}

func imagePost(params : NSMutableDictionary, image: UIImage, url: String, postCompleted: (succeeded: Bool, msg: AnyObject) -> ()){
    let request = NSMutableURLRequest(URL: NSURL(string: url)!)
    let session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"


    let imageData = UIImageJPEGRepresentation(image, 0.9)
    var base64String = self.percentEscapeString(imageData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))) // encode the image
    print(base64String)
    params["image"] = [ "content_type": "image/jpeg", "filename":"test.jpg", "file_data": base64String]
    do{
        request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions(rawValue: 0))
    }catch{
        print(error)
    }

    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        NSOperationQueue.mainQueue().addOperationWithBlock {
            var err: NSError?
            var json:NSDictionary?
            do{
                json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
            }catch{
                print(error)
                err = error as NSError
            }

            // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
            if(err != nil) {
                print("Response: \(response)")
                let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Body: \(strData!)")
                print(err!.localizedDescription)
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Error could not parse JSON: '\(jsonStr)'")
                postCompleted(succeeded: false, msg: "Error")
            }else {

                // The JSONObjectWithData constructor didn't return an error. But, we should still
                // check and make sure that json has a value using optional binding.
                if let parseJSON = json {
                    // Okay, the parsedJSON is here, let's get the value for 'success' out of it
                    if let success = parseJSON["success"] as? Bool {
                        //print("Success: \(success)")
                        postCompleted(succeeded: success, msg: parseJSON["message"]!)
                    }
                    return
                }
                else {
                    // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                    let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                    print("Error could not parse JSON: \(jsonStr)")
                    postCompleted(succeeded: false, msg: "Unable to connect")
                }
            }
        }
    })

    task.resume()
}

PHP脚本

$json = file_get_contents('php://input');
$obj = json_decode($json);

if($obj->image->content_type == "image/jpeg"){
     $filename = $obj->id . time() . ".jpg";
     $target_file = "userImages/$filename";
     if(file_put_contents($target_file, $obj->image->file_data)){
        $return_data = ["success"=>true, "message"=>"The photo has been uploaded."];
    } else {
        $return_data = ["success"=>false, "message"=>"Sorry, there was an error uploading your photo."];
    }
}else{
    $return_data = ["success"=>false,"message"=>"Not a JPEG image"];
}

上传之前的base64部分。

%2F9j%2F4AAQSkZJRgABAQAASABIAAD%2F4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAlqADAAQAAAABAAAAyAAAAAD%2F7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs%2BEJ%2B%2F8AAEQgAyACWAwEiAAIRAQMRAf

上传后的base64部分。

%2F9j%2F4AAQSkZJRgABAQAASABIAAD%2F4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAlqADAAQAAAABAAAAyAAAAAD%2F7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs%2BEJ%2B%2F8AAEQgAyACWAwEiAAIRAQMRAf

有人发现任何问题吗?

2个回答

3

看起来这段代码在PHP中不能替换base64中不需要的字符。

func percentEscapeString(string: String) -> String {
    return CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
        string,
        nil,
        ":/?@!$&'()*+,;=",
        CFStringBuiltInEncodings.UTF8.rawValue) as String;
}

我把它拿出来并修改了我的php代码,以替换不需要的字符。
if($obj->image->content_type == "image/jpeg"){
    $filename = $obj->id . time() . ".jpg";
    $target_file = "userImages/$filename";
    $data = str_replace(' ', '+', $obj->image->file_data);
    $data = base64_decode($data);
    if(file_put_contents($target_file, $data)){
        $return_data = ["success"=>true, "message"=>"The photo has been uploaded."];
    } else {
        $return_data = ["success"=>false, "message"=>"Sorry, there was an error uploading your photo."];
    }
}else{
    $return_data = ["success"=>false,"message"=>"Not a JPEG image"];
}

这对我很有帮助。

它说,在iOS 9中,cfurlcreatestringbyaddingpercentescapes已被弃用。 - Sujay U N

0

|*| Swift2 代码:将图像转换为字符串以发送到 Php 服务器

let NamImjVar = UIImage(named: "NamImjFyl")
let ImjDtaVar = UIImageJPEGRepresentation(NamImjVar!, 1)
let ImjSrgVar = ImjDtaVar!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue:0))

|*| PHP 代码:将字符串数据转换回图像并保存在服务器上

<?php

    $NamImjSrgVar = $_REQUEST["ImjKey"];
    header('Content-Type: image/jpeg');

    $NamImjDtaVar = str_replace(' ', '+', $NamImjSrgVar);
    $NamImjHexVar = base64_decode($NamImjDtaVar);

    file_put_contents("NamFyl.jpg", $NamImjHexVar)

?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接