使用 iOS swift 代码访问 flutter assets

Accessing flutter assets with iOS swift code

我在 swift 中为 flutter 编写了一个 iOS 插件,我必须将两个图像传递给它。我正在尝试通过 swift 代码从我的 flutter 资产中访问图像。

我检查了文档,objective-c 中只有一些代码可以解决我的问题。 https://flutter.dev/docs/development/ui/assets-and-images#asset-variants

flutter文档中给出的代码是这样的:

NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key 
ofType:nil];

我想得到一个 URL 的图像,如果上面的代码在 swift.

中,则可以访问该图像

类似于

所以我在 Swift 中找到了答案,它是这样的:

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
}

在外部作用域中(在 class 中定义,在我的例子中是 SwiftImageProcessPlugin)我定义了实例变量作用域中使用的注册器变量:

var registrar: FlutterPluginRegistrar? = nil

然后用它来访问我的资产图像,如下所示:

let key = registrar?.lookupKey(forAsset: "Images/topImage.png")
let topPath = Bundle.main.path(forResource: key, ofType: nil)!
let topImage: UIImage = UIImage(contentsOfFile: topPath)!

这部分完整的示例代码是这样的:

@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
    }
}

和函数:

@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)
        }