I've written an iOS plugin in swift for flutter which I have to pass two images to it. I'm trying to access an Image from my flutter assets via swift Code.
I've checked the documents and there is only some code in objective-c for my problem. https://flutter.dev/docs/development/ui/assets-and-images#asset-variants
The code given in flutter documents is this:
NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key
ofType:nil];
I want to get a URL to the image which could be accessible if the code above was in swift.
Similar to Is there a way to access Flutter resources from native code?
So I've found the answer in Swift and it goes like this:
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "image_process_plugin", binaryMessenger: registrar.messenger())
let instance = SwiftImageProcessPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
//giving access to the plugin registrar and since it's static we can access variables from outer scope:
instance.registrar = registrar
}
in the outer scope(in the class defined, which in my case was SwiftImageProcessPlugin) I defined the registrar variable used in the scope for the instance variable:
var registrar: FlutterPluginRegistrar? = nil
and then used it to access my asset Image like this:
let key = registrar?.lookupKey(forAsset: "Images/topImage.png")
let topPath = Bundle.main.path(forResource: key, ofType: nil)!
let topImage: UIImage = UIImage(contentsOfFile: topPath)!
Complete example code for this part is like this:
@available(iOS 10.0, *)
public class SwiftImageProcessPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "image_process_plugin", binaryMessenger: registrar.messenger())
let instance = SwiftImageProcessPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
//giving access to the plugin registrar and since it's static we can access variables from outer scope:
instance.registrar = registrar
}
//defining registrar variable:
var registrar: FlutterPluginRegistrar? = nil
//handling the method:
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
//MARK: photo sharing
if call.method == "preparePhotoForSharing2"{
let values = call.arguments as! NSDictionary
preparePhotoForSharing2(result: result, values: values)
}
else {
result(FlutterMethodNotImplemented)
return
}
}
and the function:
@available(iOS 10.0, *)
func preparePhotoForSharing2(result: @escaping FlutterResult, values: NSDictionary){
DispatchQueue.global(qos: .userInitiated).async {
let srcPath: String = values["srcPath"] as! String
let destPath: String = values["destPath"] as! String
let assetImagePath: String = values["assetImagePath"] as! String
// setting source image and getting height and width:
let srcUrl: URL = URL(fileURLWithPath: srcPath)
let srcImage: UIImage = UIImage(contentsOfFile: srcUrl.path)!
let srcheightInPoints = srcImage.size.height
let srcheightInPixels = srcheightInPoints * srcImage.scale
let srcwidthInPoints = srcImage.size.width
let srcwidthInPixels = srcwidthInPoints * srcImage.scale
// setting asset image and getting height and width:
let key = self.registrar?.lookupKey(forAsset: assetImagePath)
let assetPath = Bundle.main.path(forResource: key, ofType: nil)!
let assetImage: UIImage = UIImage(contentsOfFile: assetPath)!
let assetheightInPoints = assetImage.size.height
let assetheightInPixels = assetheightInPoints * assetImage.scale
let assetwidthInPoints = assetImage.size.width
let assetwidthInPixels = assetwidthInPoints * assetImage.scale
let cWidth:Int = Int(assetwidthInPixels)
let _1Height:Int = Int(Double(assetwidthInPixels / srcwidthInPixels) * Double(srcheightInPixels));
let cHeight:Int = _1Height + Int(assetheightInPixels)
//starting to process the image:
let size = CGSize(width: cWidth, height: cHeight)
UIGraphicsBeginImageContext(size)
let areaSize = CGRect(x: 0, y: 0, width: cWidth, height: _1Height)
srcImage.draw(in: areaSize)
let areaSize2 = CGRect(x: 0, y: _1Height, width: cWidth, height: Int(assetheightInPixels))
assetImage.draw(in: areaSize2, blendMode: .normal, alpha: 1)
let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
let newUrl: URL = URL(fileURLWithPath: destPath)
//saving the new image to the given address
do{ try newImage.jpegData(compressionQuality: 1.0)?.write(to: newUrl)}
catch {
print(Error.self)
DispatchQueue.main.sync {
result("0")
}
}
// ending the image process
UIGraphicsEndImageContext()
DispatchQueue.main.sync {
result(nil)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With