Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 快速获取图像';s显示尺寸_Swift_Xcode_Swiftui_Apple Vision - Fatal编程技术网

Swift 快速获取图像';s显示尺寸

Swift 快速获取图像';s显示尺寸,swift,xcode,swiftui,apple-vision,Swift,Xcode,Swiftui,Apple Vision,我试图获得显示图像的尺寸,以便在使用苹果视觉框架识别的文本上绘制边界框。 所以我用这个函数按下一个按钮来运行VnRecognitizeExtrequest Upp func readImage(image:NSImage, completionHandler:@escaping(([VNRecognizedText]?,Error?)->()), comp:@escaping((Double?,Error?)->())) { var recognizedTexts = [VNRec

我试图获得显示图像的尺寸,以便在使用苹果视觉框架识别的文本上绘制边界框。 所以我用这个函数按下一个按钮来运行VnRecognitizeExtrequest Upp

func readImage(image:NSImage, completionHandler:@escaping(([VNRecognizedText]?,Error?)->()), comp:@escaping((Double?,Error?)->())) {

var recognizedTexts = [VNRecognizedText]()
var rr = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
let requestHandler = VNImageRequestHandler(cgImage: image.cgImage(forProposedRect: &rr, context: nil, hints: nil)!
, options: [:])
let textRequest = VNRecognizeTextRequest { (request, error) in
    guard let observations = request.results as? [VNRecognizedTextObservation] else { completionHandler(nil,error)
        return
    }
    for currentObservation in observations {
        let topCandidate = currentObservation.topCandidates(1)
        if let recognizedText = topCandidate.first {

            recognizedTexts.append(recognizedText)
        }
    }
    completionHandler(recognizedTexts,nil)
}

textRequest.recognitionLevel = .accurate
textRequest.recognitionLanguages = ["es"]
textRequest.usesLanguageCorrection = true

textRequest.progressHandler = {(request, value, error) in
    comp(value,nil)
}
try? requestHandler.perform([textRequest])
}

并使用此结构和函数计算边界框偏移

struct DisplayingRect:Identifiable {

var id = UUID()
var width:CGFloat = 0
var height:CGFloat = 0
var xAxis:CGFloat = 0
var yAxis:CGFloat = 0

init(width:CGFloat, height:CGFloat, xAxis:CGFloat, yAxis:CGFloat) {
    self.width = width
    self.height = height
    self.xAxis = xAxis
    self.yAxis = yAxis
}
}

如果我使用原始图像的尺寸,我会得到这些结果

但如果我加上

                Image(nsImage: self.img!)
                  .resizable()
                  .scaledToFit()
我得到了这些结果

是否有方法获取图像尺寸并传递它们,以获得所显示图像的正确大小?我也需要这个,因为我有时不能显示整个图像,需要缩放它


非常感谢

苹果没有将框架传递给每个视图,而是选择给您一个单独的视图,将其框架作为参数传递给其子闭包

struct Example: View {
  var body: some View {
    GeometryReader { geometry in
      Image(systemName: "check")
        .onAppear {
          print(geometry.frame(in: .local))
        }
    }
  }
}


我会在背景上使用
GeometryReader
,这样它就能准确读取图像的大小,如下所示

@State var imageSize: CGSize = .zero // << or initial from NSImage
...
Image(nsImage: self.img!)
    .resizable()
    .scaledToFit()
    .background(rectReader())

// ... somewhere below 
private func rectReader() -> some View {
    return GeometryReader { (geometry) -> AnyView in
        let imageSize = geometry.size
        DispatchQueue.main.async {
            print(">> \(imageSize)") // use image actual size in your calculations
            self.imageSize = imageSize
        }
        return AnyView(Rectangle().fill(Color.clear))
    }
}
@State var imageSize:CGSize=.zero//一些视图{
返回GeometryReader{(几何)->中的任意视图
让imageSize=geometry.size
DispatchQueue.main.async{
打印(“>>\(imageSize)”//在计算中使用图像的实际大小
self.imageSize=imageSize
}
返回任意视图(矩形().fill(Color.clear))
}
}

当然,这是解决方案,但在创建边界框的函数中计算这些值时,我会得到一个错误的结果。我会得到完全相同的帧,就像我没有调整大小一样。我会得到这个警告,帧实际上会改变,但我无法捕获值。当我想要捕获图像大小时,我收到了一个尴尬的警告:“在视图更新期间修改状态,这将导致未定义的行为。”我明白了。如果您收到这样的警告,您必须在下一个事件周期异步调度修改,因此新值将应用于以下重画。你可以找到一个例子来说明如何做到这一点。更新显示了如何在
@State
中存储获取的imageSize值,该值可用于视图代码的其他部分。非常感谢它的工作!!!我通过主队列进行了var更新,我忘了这是一个异步调用。实际上,它们在@State vars中,我认为没有必要分派修改。
struct Example: View {
  var body: some View {
    GeometryReader { geometry in
      Image(systemName: "check")
        .onAppear {
          print(geometry.frame(in: .local))
        }
    }
  }
}

@State var imageSize: CGSize = .zero // << or initial from NSImage
...
Image(nsImage: self.img!)
    .resizable()
    .scaledToFit()
    .background(rectReader())

// ... somewhere below 
private func rectReader() -> some View {
    return GeometryReader { (geometry) -> AnyView in
        let imageSize = geometry.size
        DispatchQueue.main.async {
            print(">> \(imageSize)") // use image actual size in your calculations
            self.imageSize = imageSize
        }
        return AnyView(Rectangle().fill(Color.clear))
    }
}