diff --git a/android/src/main/kotlin/com/example/imagegallerysaver/ImageGallerySaverPlugin.kt b/android/src/main/kotlin/com/example/imagegallerysaver/ImageGallerySaverPlugin.kt index a6ada88..e4f1f31 100644 --- a/android/src/main/kotlin/com/example/imagegallerysaver/ImageGallerySaverPlugin.kt +++ b/android/src/main/kotlin/com/example/imagegallerysaver/ImageGallerySaverPlugin.kt @@ -151,32 +151,49 @@ class ImageGallerySaverPlugin : FlutterPlugin, MethodCallHandler { name: String? ): HashMap { // check parameters - if (bmp == null || quality == null) { + if (bmp == null || quality == null || name.isNullOrEmpty()) { return SaveResultModel(false, null, "parameters error").toHashMap() } + // check applicationContext val context = applicationContext ?: return SaveResultModel(false, null, "applicationContext null").toHashMap() + var fileUri: Uri? = null var fos: OutputStream? = null var success = false + try { - fileUri = generateUri("png", name = name) + // Get file extension from name + val fileExtension = getFileExtensionFromName(name) + + // Determine the compression format based on the extension + val compressFormat = when (fileExtension) { + "png" -> Bitmap.CompressFormat.PNG + "jpeg", "jpg" -> Bitmap.CompressFormat.JPEG + else -> Bitmap.CompressFormat.PNG // Default to PNG if extension is not recognized + } + + // Generate the file URI (use the extension passed as argument) + fileUri = generateUri(fileExtension, name) + if (fileUri != null) { fos = context.contentResolver.openOutputStream(fileUri) if (fos != null) { println("ImageGallerySaverPlugin $quality") - bmp.compress(Bitmap.CompressFormat.PNG, quality, fos) + // Compress bitmap with the correct format and quality + bmp.compress(compressFormat, quality, fos) fos.flush() success = true } } } catch (e: IOException) { - SaveResultModel(false, null, e.toString()).toHashMap() + return SaveResultModel(false, null, e.toString()).toHashMap() } finally { fos?.close() bmp.recycle() } + return if (success) { sendBroadcast(context, fileUri) SaveResultModel(fileUri.toString().isNotEmpty(), fileUri.toString(), null).toHashMap() @@ -185,6 +202,13 @@ class ImageGallerySaverPlugin : FlutterPlugin, MethodCallHandler { } } + private fun getFileExtensionFromName(name: String): String { + // Extract the file extension from the name and convert to lowercase + val extension = name.substringAfterLast('.', "").toLowerCase(Locale.getDefault()) + return extension + } + + private fun saveFileToGallery(filePath: String?, name: String?): HashMap { // check parameters if (filePath == null) { diff --git a/ios/Classes/SwiftImageGallerySaverPlugin.swift b/ios/Classes/SwiftImageGallerySaverPlugin.swift index f63f50b..4643da1 100644 --- a/ios/Classes/SwiftImageGallerySaverPlugin.swift +++ b/ios/Classes/SwiftImageGallerySaverPlugin.swift @@ -13,36 +13,72 @@ public class SwiftImageGallerySaverPlugin: NSObject, FlutterPlugin { registrar.addMethodCallDelegate(instance, channel: channel) } + // Function to get the file extension from a name + func getFileExtension(from fileName: String) -> String? { + // Extract the file extension from the file name + let fileExtension = (fileName as NSString).pathExtension.lowercased() + + // Check if the extension is either "png", "jpeg", or "jpg" + if fileExtension == "png" || fileExtension == "jpeg" || fileExtension == "jpg" { + return fileExtension + } else { + return nil // Return nil if not a supported image format + } + } + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - self.result = result - if call.method == "saveImageToGallery" { - let arguments = call.arguments as? [String: Any] ?? [String: Any]() - guard let imageData = (arguments["imageBytes"] as? FlutterStandardTypedData)?.data, - let image = UIImage(data: imageData), - let quality = arguments["quality"] as? Int, - let _ = arguments["name"], - let isReturnImagePath = arguments["isReturnImagePathOfIOS"] as? Bool + self.result = result + if call.method == "saveImageToGallery" { + let arguments = call.arguments as? [String: Any] ?? [String: Any]() + guard let imageData = (arguments["imageBytes"] as? FlutterStandardTypedData)?.data, + let image = UIImage(data: imageData), + let quality = arguments["quality"] as? Int, + let imageName = arguments["name"] as? String, + let isReturnImagePath = arguments["isReturnImagePathOfIOS"] as? Bool else { return } - let newImage = image.pngData()! - saveImage(UIImage(data: newImage) ?? image, isReturnImagePath: isReturnImagePath) - } else if (call.method == "saveFileToGallery") { - guard let arguments = call.arguments as? [String: Any], - let path = arguments["file"] as? String, - let _ = arguments["name"], - let isReturnFilePath = arguments["isReturnPathOfIOS"] as? Bool else { return } - if (isImageFile(filename: path)) { - saveImageAtFileUrl(path, isReturnImagePath: isReturnFilePath) - } else { - if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(path)) { - saveVideo(path, isReturnImagePath: isReturnFilePath) - }else{ - self.saveResult(isSuccess:false,error:self.errorMessage) + + // Get file extension from the image name + guard let fileExtension = getFileExtension(from: imageName) else { + // Handle unsupported file formats + result(FlutterError(code: "UNSUPPORTED_FORMAT", message: "Unsupported file format", details: nil)) + return + } + + var newImageData: Data? + + // Depending on the file extension, choose the appropriate data format + if fileExtension == "png" { + newImageData = image.pngData() // Save as PNG + } else if fileExtension == "jpeg" || fileExtension == "jpg" { + newImageData = image.jpegData(compressionQuality: CGFloat(quality) / 100.0) // Save as JPEG with specified quality } + + // If the data is not nil, save the image + if let newImageData = newImageData { + saveImage(UIImage(data: newImageData) ?? image, isReturnImagePath: isReturnImagePath) + } else { + result(FlutterError(code: "IMAGE_ERROR", message: "Error creating image data", details: nil)) + } + } else if (call.method == "saveFileToGallery") { + guard let arguments = call.arguments as? [String: Any], + let path = arguments["file"] as? String, + let _ = arguments["name"], + let isReturnFilePath = arguments["isReturnPathOfIOS"] as? Bool else { return } + + if (isImageFile(filename: path)) { + saveImageAtFileUrl(path, isReturnImagePath: isReturnFilePath) + } else { + if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(path)) { + saveVideo(path, isReturnImagePath: isReturnFilePath) + } else { + self.saveResult(isSuccess: false, error: self.errorMessage) + } + } + } else { + result(FlutterMethodNotImplemented) } - } else { - result(FlutterMethodNotImplemented) - } } + func saveVideo(_ path: String, isReturnImagePath: Bool) { if !isReturnImagePath {