【问题标题】:Encoding base64 string to image in swift received from mysql将base64字符串编码为从mysql接收的swift中的图像
【发布时间】:2018-06-28 10:30:24
【问题描述】:

我从 mysql 接收一个 base64 字符串(存储为 blob)并尝试像这样对其进行编码:

func loadImage() {
    var request = URLRequest(url: URL(string: URL_IMAGES)!)
    request.httpMethod = "POST"
    let userid = self.defaultValues.integer(forKey: "userid")
    let postString = "userid=\(userid)"
    request.httpBody = postString.data(using: .utf8)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print("error=\(String(describing: error))")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(String(describing: response))")
        }

        let responseString = String(data: data, encoding: .utf8)
        if let encodedImage = responseString,
            let imageData =  NSData(base64Encoded: encodedImage, options: .ignoreUnknownCharacters),
            let image = UIImage(data: imageData as Data) {
            print(image.size)
        }
    }
    task.resume()
}

而 php 文件看起来是这样的:

<?php
$userid=$_POST["userid"];
$conn = mysqli_connect(connection);
if ($conn->connect_error) {
    die("Connection failed: " . $conn>connect_error);
} 
$sql = "SELECT profilepicture FROM users WHERE id = $userid";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
     while($row = $result->fetch_assoc()) {
         $out[]=$row;
     }
    echo json_encode($out);
} else {
  echo "0 results";
}
?>

EDIT 2* 这就是我将图像存储到数据库中的方式:

@objc func updateUser(sender: UIButton!) {
    let refreshAlert = UIAlertController(title: "Update profile?", message: "Do you want to update your profile? This will log you out to update the data!", preferredStyle: UIAlertControllerStyle.alert)
    refreshAlert.view.tintColor = UIColor.red
    refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in

        let URL_REQUEST = "request"

        self.messageLbl.text = ""

        var request = URLRequest(url: URL(string: URL_REQUEST)!)
        request.httpMethod = "POST"
        let userid = self.defaultValues.integer(forKey: "userid")
        let password = self.passWordTf.text!
        let email = self.eMailTf.text!
        let image = self.imageView.image!
        guard let pictStr = self.convertImageBase64(image: image) else {
            return
        }
        let postString = "id=\(userid)&password=\(password)&email=\(email)&profilepicture=\(pictStr)"
        request.httpBody = postString.data(using: .utf8)
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                print("error=\(String(describing: error))")
                return
            }

            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(String(describing: response))")
            }

            let responseString = String(data: data, encoding: .utf8)
            print("responseString = \(String(describing: responseString))")
        }
        task.resume()

        if (self.eMailTf.text != self.defaultValues.string(forKey: "useremail")) {
            self.defaultValues.set(self.eMailTf.text, forKey: "useremail")
        }
        self.navigationController?.popViewController(animated: true)
    }))

    refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action: UIAlertAction!) in
        print("Handle Cancel Logic here")
    }))

    present(refreshAlert, animated: true, completion: nil)
}

EDIT 2* 这是编码函数:

func convertImageBase64(image: UIImage) -> String? {
    guard let pictData = UIImagePNGRepresentation(image) else {
        return nil
    }
    let strBase64: String = pictData.base64EncodedString(options: [])
    return strBase64
}

EDIT 2* 以及用于存储的 php 文件:

<?php
$userid=$_POST["userid"];
$password=$_POST["password"];
$pass = md5($password);
$email=$_POST["email"];
$profilepicture=$_POST["profilepicture"];


$conn = mysqli_connect(connection);

if ($conn->connect_error) {
 die("Connection failed: " . $conn->connect_error);
} 

$sql =("UPDATE users SET password='".$pass."' ,  email='".$email."' , profilepicture='".$profilepicture."' WHERE id=".$userid."");

if ($conn->query($sql) === TRUE) {
    echo "Record updated successfully";
} else {
    echo "Error updating record: " . $conn->error;
}

$conn->close();
?>

这是与this 类似的问题,但即使尝试了所有答案也对我不起作用。我得到的响应是正确的,但我无法对其进行编码,因为我总是试图编码:

我也尝试过很多这样的事情:

Decode base64_encode Image from JSON in Swift

编辑 1

im 接收的字符串具有以下前缀: "[{\"头像\":\"iVBORw0KGgoAAAANSUhE...

是否可以在没有此前缀的情况下转换字符串,或者前缀是否与转换字符串无关?

编辑 2

【问题讨论】:

    标签: php mysql swift xcode


    【解决方案1】:

    您的服务器端代码返回 JSON 数据,其中包含使用 fetch_assoc() 检索的 assoc 数组。

    我建议你更新服务器端代码,因为它返回的不是图像数据,所以最好只发送图像数据。

    但如果您想按原样使用服务器端代码,您可能需要在loadImage 中编写类似这样的内容:

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                print("error=\(error?.localizedDescription ?? "nil")")
                return
            }
    
            guard let httpResponse = response as? HTTPURLResponse else {
                print("response is not an HTTPURLResponse")
                return
            }
            guard httpResponse.statusCode == 200 else {
                print("statusCode should be 200, but is \(httpResponse.statusCode)")
                print("response = \(httpResponse)")
                return
            }
    
            do {
                //First decode the response body as JSON
                let json = try JSONSerialization.jsonObject(with: data)
                //The decoded object should be a JSON array containing one JSON object
                guard let arr = json as? [[String: Any]], !arr.isEmpty else {
                    print("json is not an array, or is empty")
                    return
                }
                //Use only the first record
                let person = arr[0]
                //Retrieve the column value of "profilepicture" in the first record
                guard let encodedImage = person["profilepicture"] as? String else {
                    print("NO profilepicture")
                    return
                }
                //Decode it into binary data as Base64
                guard let imageData =  Data(base64Encoded: encodedImage, options: .ignoreUnknownCharacters) else {
                    print("encodedImage is not a valid Base64")
                    return
                }
                //Convert the decoded binary data into an image
                guard let image = UIImage(data: imageData) else {
                    print("imageData is in a unsupported format or is not an image")
                    return
                }
                print(image.size)
                //Use `image` here...
            } catch {
                print(error)
            }
        }
        task.resume()
    

    您可能需要修改某些部分,但您可以轻松找到修复的地方,因为我在坏情况下嵌入了许多 print

    【讨论】:

    • 非常感谢!我终于可以在我的 ImageView 中显示存储在我的数据库中的图像了。现在我面临的问题是,我无法将其存储在数据库中,因为我更改了一些功能以使下载工作:/如果您能帮助我解决已编辑的(编辑 2)问题,我将非常高兴。
    • 请描述I can't store it in the database。有什么错误吗?某种意想不到的结果?我没有足够的时间来分析没有 cmets 的代码...您为什么不直接恢复原始帖子中的原始代码?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 2013-03-18
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多