Кодирование строки base64 к изображению в swift, полученном из mysql - PullRequest
0 голосов
/ 28 июня 2018

Я получаю строку base64 из mysql (хранится как 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";
}
?>

РЕДАКТИРОВАТЬ 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)
}

РЕДАКТИРОВАТЬ 2 * Это функция кодирования:

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

РЕДАКТИРОВАТЬ 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();
?>

этот вопрос похож на этот , но даже попытка ответить на все вопросы у меня не сработала. Ответ, который я получаю, правильный, но я не могу его закодировать, так как я всегда получаю ноль, пытаясь закодировать:

Я тоже много чего пробовал:

Декодировать base64_encode Изображение из JSON в Swift

РЕДАКТИРОВАТЬ 1

Строка, которую я получаю, имеет следующий префикс: "[{\" Profilepicture \ ": \" iVBORw0KGgoAAAANSUhE ...

Возможно ли преобразовать строку без этого префикса или префикс даже не имеет значения для преобразования строки?

РЕДАКТИРОВАТЬ 2

1 Ответ

0 голосов
/ 30 июня 2018

Ваш серверный код возвращает данные JSON, содержащие массив ассоциированных массивов, полученных с помощью fetch_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 в плохих случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...