使用 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)
}
我在 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)
}