php – UIImage taken from iPhone camera turns black when uploaded


I’m currently working on an iOS app in Swift that involves uploading images to a server. The image uploading works fine for most images, but I’ve noticed that when I take a photo directly from the iPhone camera and try to upload it, the image appears black on the server.

Here’s the code I’m using to handle the image uploading:

    func stripMetaData(from image: UIImage) -> UIImage? {
        guard let cgImage = image.cgImage else { return nil }
        let strippedImage = UIImage(cgImage: cgImage, scale: image.scale, orientation: image.imageOrientation)
        return strippedImage
    }

    func publishData() {
        isLoading = true

        guard let uiImage = selectedImage?.asUIImage() else { return }
        guard let strippedImage = stripMetaData(from: uiImage) else { return }
        guard let imageData = strippedImage.jpegData(compressionQuality: 1.0) else { return }
        uploadImage(imageData: imageData)
    }
    func uploadImage(imageData: Data) {
        let url = URL(string: "https://cloud.ellicode.com/mobile/upload_file.php")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        let boundary = UUID().uuidString
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        let parameters: [String: Any] = [
            "SECRET_KEY": "05fe5e2d-8878-4ba6-9bfc-ccc4498eb219",
            "type": assetType,
            "name": assetName,
            "description": assetDesc,
            "price" : assetPrice,
            "userID" : UserID
        ]
        let dataBody = createDataBody(withParameters: parameters, media: [(data: imageData, mimeType: "image/jpeg", filename: "image.jpg")], boundary: boundary, fileKey: assetType)
        request.httpBody = dataBody
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("Error: \(error)")
                isLoading = false
            } else if let data = data {
                let str = String(data: data, encoding: .utf8)
                print("Received data:\n\(str ?? "")")
                print("Request Headers: \(request.allHTTPHeaderFields ?? [:])")
                if let bodyString = String(data: dataBody, encoding: .utf8) {
                    print("Request Body: \(bodyString)")
                }
                isLoading = false
                newsheet = false
            }
        }
        task.resume()
    }

    func createDataBody(withParameters parameters: [String: Any], media: [(data: Data, mimeType: String, filename: String)], boundary: String, fileKey: String) -> Data {
        let lineBreak = "\r\n"
        var body = Data()

        for (key, value) in parameters {
            body.append("--\(boundary)\(lineBreak)".data(using: .utf8)!)
            body.append("Content-Disposition: form-data; name=\"\(key)\"\(lineBreak)\(lineBreak)".data(using: .utf8)!)
            body.append("\(value)\(lineBreak)".data(using: .utf8)!)
        }

        for item in media {
            body.append("--\(boundary)\(lineBreak)".data(using: .utf8)!)
            body.append("Content-Disposition: form-data; name=\"\(fileKey)\"; filename=\"\(item.filename)\"\(lineBreak)".data(using: .utf8)!)
            body.append("Content-Type: \(item.mimeType)\(lineBreak)\(lineBreak)".data(using: .utf8)!)
            body.append(item.data)
            body.append(lineBreak.data(using: .utf8)!)
        }

        body.append("--\(boundary)--\(lineBreak)".data(using: .utf8)!)

        return body
    }


    func loadAssets() {
        
        // API endpoint URL
        let apiUrl = URL(string: "https://cloud.ellicode.com/mobile/all_assets.php")!
        
        // Prepare the request
        var request = URLRequest(url: apiUrl)
        request.httpMethod = "POST"
        
        // Set the request body data
        let parameters: [String: String] = [
            "SECRET_KEY": "05fe5e2d-8878-4ba6-9bfc-ccc4498eb219",
        ]
        
        request.httpBody = parameters
            .map { "\($0)=\($1)" }
            .joined(separator: "&")
            .data(using: .utf8)
        
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        
        // Create a URLSession task
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let httpResponse = response as? HTTPURLResponse {
                print("HTTP Status Code: \(httpResponse.statusCode)")
            }
            if let data = data {
                
                do {
                    // Decode the response
                    let decoder = JSONDecoder()
                    let apiResponse = try decoder.decode(ContentResponse.self, from: data)
                    
                    // Handle the decoded response
                    DispatchQueue.main.async {
                        assets = []
                        apiResponse.Data.forEach { data in
                            switch data {
                            case .content(let content):
                                assets.append(content)
                            case .string(let errorMessage):
                                // Handle String
                                print("Error: \(errorMessage)")
                                // Show an alert or handle the error as needed
                                alert = true
                                alertText = errorMessage
                            case .message(_):
                                alert = true
                                alertText = "Undefined content type"
                            }
                        }
                    }
                    
                } catch {
                    print("Error decoding response: \(error)")
                    alert = true
                    alertText = "Failed to decode response."
                }
            } else if let error = error {
                print("Error: \(error.localizedDescription)")
                alert = true
                alertText = "Failed to fetch data from the server."
            }
        }.resume()
    }

I’ve tried several things to debug this issue:

  1. Checked the image before upload: The image appears fine on the device before it’s uploaded.
  2. Checked the server-side script: The server-side script seems to be working fine as it correctly processes and stores other images.
  3. Printed the server response: The server response doesn’t indicate any issues with the image upload.
  4. Checked the HTTP status code: The status code returned from the server is 200, indicating that the request was successful.

I’ve also tried correcting the image orientation before converting it to data, and stripping the metadata from the image, but neither of these solutions resolved the issue.

Has anyone else encountered this issue or have any suggestions on what else I could try?

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img