Search code examples
iosswiftuiimagepickercontrollernsfilemanager

Swift: Image size is increasing after writing that image to folder even after compressing the image


I'm saving an image picked from Photos in a Document folder.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    guard let selectedImage = info[.originalImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }
    selectedImage.jpegData(compressionQuality: 0.0).fileSize() //Printing size as 4284217 bytes|4.3 MB
    if let imageData = selectedImage.jpeg(.lowest) {
        imageData.fileSize() //Printing size as 4284217 bytes|4.3 MB
        let compressedImage = UIImage(data: imageData)?.fixOrientation()
        saveImageInDocuments(compressedImage!)
    }
    picker.dismiss(animated: true, completion: nil)
}

After selecting the image and compressing to minimum size, I have printed the size of Image. Next step is to save Image to Documents Folder.

func saveImageInDocuments(_ image: UIImage) {
    let imageName = String(Date().toMillis())
    let fileURL = documentsDirectoryURL.appendingPathComponent("\(CUST_APP_DOC)/\(imageName).png")
    print(fileURL.path)

    if !FileManager.default.fileExists(atPath: fileURL.path) {
        do {
            try image.pngData()!.write(to: fileURL)                
            print("Saved filename: \(imageName).png size: \(calculateFileSize(path: String(describing: fileURL)).0)")
        } catch {
            print(error)
        }
    } else {
        print("Image Not Added")
    }
}

Methods used to get size of the image and calculate the size of Image saved at path

 func calculateFileSize(path: String) -> (String, Double) {
    let absolutePath = path.replacingOccurrences(of: "file://", with: "")
    let fileAttributes = try! FileManager.default.attributesOfItem(atPath: absolutePath)
    let fileSizeNumber = fileAttributes[FileAttributeKey.size] as! NSNumber
    let fileSize = fileSizeNumber.int64Value
    var sizeMB = Double(fileSize / 1024)
    sizeMB = Double(sizeMB / 1024)
    print(String(format: "%.2f", sizeMB) + " MB")
    return (String(format: "%.2f", sizeMB) + " MB", sizeMB)
}

extension Data {
    func fileSize() {
        let bcf = ByteCountFormatter()
        bcf.allowedUnits = [.useMB] // optional: restricts the units to MB only
        bcf.countStyle = .file
        let string = bcf.string(fromByteCount: Int64(self.count))
        print("Printing size as \(self.count) bytes|\(string) MB")
    }
}

The issue is that after selecting the image the image file size is 4.3 MB but while after saving the image in folder. The size of image is coming "Saved filename: 1546593850872.png size: 29.86 MB"

Why is this happening? If anyone can help to explain this, I will be thankful to the person.


Solution

  • After searching for this whole day, I found the answer to this scenario.

    In didFinishPickingMediaWithInfo I was compressing the image to JPEG where the image size was getting reduced. Then while writing the image to directory saveImageInDocuments, I was converting the JPEG image again to PNG using this line of code.

    try image.pngData()!.write(to: fileURL)

    Converting the image to PNG was increasing its size.

    For solution I have modified this method:

    func saveImageInDocuments(_ imageData: Data) {
        let imageName = String(Date().toMillis())
        let fileURL = documentsDirectoryURL.appendingPathComponent("\(CUST_APP_DOC)/\(imageName).png")
        print(fileURL.path)
    
        if !FileManager.default.fileExists(atPath: fileURL.path) {
            do {
                try imageData.write(to: fileURL)                
             } catch {
                print(error)
            }
        } else {
            print("Image Not Added")
        }
    }
    

    Directly saved the compressed JPEG image.