首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用异步PHPicker拾取图像后执行操作

使用异步PHPicker拾取图像后执行操作
EN

Stack Overflow用户
提问于 2022-01-28 10:24:45
回答 2查看 291关注 0票数 1

问题

要执行BitwiseAND操作(UIImage1,UIImage2),这是OpenCV框架的功能。UIImage1已经在MainVC中显示:

代码语言:javascript
复制
@IBOutlet weak var presentedImage: UIImageView!

因此,当用户需要时,必须另外选择UIImage2。值得提及的 :

@IBOutlet弱变量presentedImage: UIImageView!

的选择也与PHPicker相同,如UIImage2

目前解决问题的想法..。

创建了2个标志:

  • 第一次检查,当前用PHPicker选择的图像是否用于

@IBOutlet弱变量presentedImage: UIImageView!

或者是为了“比特的目的”。

这是旗子:

代码语言:javascript
复制
private var isBitwisePick: Bool = false

  • 第二个“标志”确定按位执行(和异或)

的类型

代码语言:javascript
复制
 private var bitwiseOperationType: OperationTypes.ControllerTypes.BitwiseTypes?
代码语言:javascript
复制
 enum ControllerTypes{
 /*...*/
    enum BitwiseTypes{ case AND,NOR,XOR,OR }
/*.../
}

处理用户图像采集的尝试

代码语言:javascript
复制
/* This is switch-case of callback from other viewcontroller.
In our case only this one matters
*/
case .BITWISE_VC(let bitwise):
               
            self.isBitwisePick = true //Pick image for "Bitwise purpose"
            self.bitwiseOperationType = bitwise // determines type of Bitwise 
 
            // config and present PHPicker
            var config = PHPickerConfiguration()
            config.filter = .images
            config.selectionLimit = 1
            let picker = PHPickerViewController(configuration: config)
            picker.delegate = self
            self.present(picker, animated: true)

PHPickerViewControllerDelegate

代码语言:javascript
复制
extension MainViewController:  PHPickerViewControllerDelegate{
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        dismiss(animated: true)
        print("test before async \(self.isBitwisePick)")
        if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self){
            let previousImage = self.presentedImage.image
            itemProvider.loadObject(ofClass: UIImage.self){ [weak self] image, error in
                DispatchQueue.main.async { [self] in
                    guard let self = self, let image = image as? UIImage, self.presentedImage.image == previousImage else {
                        return
                    }
                    print("Im in async \(self.isBitwisePick)")
                    if(self.isBitwisePick){
                        switch self.bitwiseOperationType{
                            case .AND:
                                self.presentedImage.image = OpenCVWrapper.bitwiseAND(self.presentedImage.image, with: image)
                                break
                            default:
                                print("the same for XOR OR NOR")
                            break
                        }
                    }
                    else{ self.presentedImage.image = image }
                }
            }
            self.isBitwisePick = false
        }
    }
}

带着线

打印(“异步前测试(self.isBitwisePick)")

我可以看到,该标志已更改,其值为true

然而..。这句话:

print("Im in异步(self.isBitwisePick)")打印值:false

我刚开始读一些关于解决方案的文章和文档,比如DispatchQueue或DispatchGroup.但我解决不了。所以我才向你寻求帮助和建议。谢谢你抽出时间:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-28 12:31:43

问题是这条线

代码语言:javascript
复制
 self.isBitwisePick = false

didFinishPicking()函数中。该行将在调用itemProvider.loadObject(ofClass:)函数的完成处理程序之前执行。然后,当您在完成处理程序中签入isBitwisePick时,它将为false。您应该将这一行移动到完成处理程序中。

编辑:

马季奇Oblak关于将第一张图像和第二张图像保存到您的数据模型中的建议很好。从图像视图中提取原始图像的方式似乎不正确,因为在按位操作之后,图像视图将包含处理过的图像,不是吗?(另外,一般来说,您不应该将数据存储在视图对象中。视图对象用于向用户显示信息和收集来自用户的输入,而不是存储数据。这就是模特的目的。(我建议您阅读MVC设计模式。还有很多其他的设计模式,但就像MVC一样,它们几乎都没有把视图当作存储数据的地方。)

票数 1
EN

Stack Overflow用户

发布于 2022-01-28 11:29:32

您的数据结构应该类似于

代码语言:javascript
复制
private var firstImage: UIImage?
private var secondImage: UIImage?

然后您可以覆盖setter或应用其他机制,如

代码语言:javascript
复制
private var firstImage: UIImage? { didSet { reevaluateImagesSet() } }
private var secondImage: UIImage? { didSet { reevaluateImagesSet() } }

private func reevaluateImagesSet() {
    imageView1.image = firstImage
    imageView2.image = secondImage

    if let firstImage = firstImage, let secondImage = secondImage {
        applyCombinedImage(firstImage, secondImage)
    }
}

private func applyCombinedImage(_ firstImage: UIImage, _ secondImage: UIImage) {
    // do the bitwise operation of yours in here
}

现在唯一的问题是如何定义您正在设置的图像。您可以使用布尔标志,也可以创建一个自定义类,使之如下所示:

代码语言:javascript
复制
   @IBAction private func selectFirstImagePressed() {
        let picker = MyPicker(controller: self)
        self.currentPicker = picker
        picker.selectImage { image in
            self.firstImage = image
        }
   }

   @IBAction private func selectSecondImagePressed() {
        let picker = MyPicker(controller: self)
        self.currentPicker = picker
        picker.selectImage { image in
            self.secondImage = image
        }
   }

然后,这个类MyPicker对应于PHPickerViewControllerDelegate,并实现了逻辑,只返回给定闭包中的图像。我希望你在实施上不会有任何问题。它主要是提取您已经拥有的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70892153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档