简体   繁体   English

从MySQL收到的Swift中将base64字符串编码为图像

[英]Encoding base64 string to image in swift received from mysql

I am receiving a base64 string from mysql (stored as blob) and try to encode it like this: 我从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()
}

And the php file looks like this: 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* And this is how Im storing the image into the database: 编辑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* This is the encoding function: 编辑2 *这是编码功能:

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

EDIT 2* And the php file for storing: 编辑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 is a similar question to this , but even trying all the answers did not work for me. 这是一个类似的问题这个 ,但即使尝试所有的答案并没有为我工作。 The response I'm getting is right but I can't encode it, since Im always getting nil trying to encode: 我得到的响应是正确的,但我无法对其进行编码,因为我总是在尝试编码时得到nil:

I have tried a lot of things like this too: 我也尝试过很多类似的事情:

Decode base64_encode Image from JSON in Swift 在Swift中从JSON解码base64_encode图像

EDIT 1 编辑1

The string im receiving has the following prefix: "[{\\"profilepicture\\":\\"iVBORw0KGgoAAAANSUhE... im接收的字符串具有以下前缀:“ [{\\” profilepicture \\“:\\” iVBORw0KGgoAAAANSUhE ...

Is it possible to convert the string without this prefix or is the prefix not even relevant to convert the string? 是否可以在没有此前缀的情况下转换字符串,或者该前缀甚至与转换字符串都不相关?

EDIT 2 编辑2

Your server side code returns JSON data containing an array of assoc arrays retrieved with fetch_assoc() . 您的服务器端代码返回JSON数据,其中包含通过fetch_assoc()检索的assoc数组的数组。

I recommend you to update the server side code, as it returns some other things than an image data, it should better send only the image data. 我建议您更新服务器端代码,因为它返回除图像数据以外的其他内容,因此最好只发送图像数据。

But if you want to use the server side code as is, you may need to write something like this in your loadImage : 但是,如果您想按原样使用服务器端代码,则可能需要在loadImage编写如下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()

You may need to modify some parts, but you can easily find where to fix as I embedded many print in bad cases. 您可能需要修改某些部分,但是当我在坏情况下嵌入许多print ,可以轻松找到要修复的地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM