swift - Swiftui 获取图像的显示尺寸
问题描述
我正在尝试获取显示图像的尺寸,以便在我使用苹果的 Vision 框架识别的文本上绘制边界框。所以我在按下具有此功能的按钮时运行 VNRecognizeTextRequest
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
}
}
func createBoundingBoxOffSet(recognizedTexts:[VNRecognizedText], image:NSImage) -> [DisplayingRect] {
var rects = [DisplayingRect]()
let imageSize = image.size
let imageTransform = CGAffineTransform.identity.scaledBy(x: imageSize.width, y: imageSize.height)
for obs in recognizedTexts {
let observationBounds = try? obs.boundingBox(for: obs.string.startIndex..<obs.string.endIndex)
let rectangle = observationBounds?.boundingBox.applying(imageTransform)
print("Rectange: \(rectangle!)")
let width = rectangle!.width
let height = rectangle!.height
let xAxis = rectangle!.origin.x - imageSize.width / 2 + rectangle!.width / 2
let yAxis = -(rectangle!.origin.y - imageSize.height / 2 + rectangle!.height / 2)
let rect = DisplayingRect(width: width, height: height, xAxis: xAxis, yAxis: yAxis)
rects.append(rect)
}
return(rects)
}
我在 ContentView 中使用此代码放置矩形
ZStack{
Image(nsImage: self.img!)
.scaledToFit()
ForEach(self.rects) { rect in
Rectangle()
.fill(Color.init(.sRGB, red: 1, green: 0, blue: 0, opacity: 0.2))
.frame(width: rect.width, height: rect.height)
.offset(x: rect.xAxis, y: rect.yAxis)
}
}
如果我使用原件的图像尺寸,我会得到这些结果
但是如果我添加
Image(nsImage: self.img!)
.resizable()
.scaledToFit()
有没有办法获取图像尺寸并传递它们并获得正在显示的图像的正确尺寸?我也需要这个,因为有时我无法显示整个图像并且需要缩放它。
非常感谢
解决方案
我会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))
}
}
推荐阅读
- excel - 使用消息框更改范围的字体颜色?和工作表选择?
- c# - AuthorizeAttribute for Web API (ASP.NET Core 2)
- c++ - 如果ap是一个指针,为什么我可以通过ap[i]来引用它的值呢?
- python - python中用户输入平方根、常数、虚数等的选项
- go - 在任何一个中都找不到包“bufio”
- c# - c# 正则表达式重复计数不能是变量
- php - Doctrine-MongoDB postLoad 在创建新文档时触发 preUpdate
- objective-c - 如何确保在 xcode 上选择第一个(第 0 个之后)段?
- tensorflow - Keras (Tensorflow) 如何在自定义损失函数中计算批次的梯度?
- python - 使用字典键对列进行分类 - 多值对