Swiftui 获取图像的显示尺寸 [英] Swiftui getting an image's displaying dimensions
问题描述
我正在尝试获取显示图像的尺寸,以便在我使用 Apple 的 Vision 框架识别的文本上绘制边界框.所以我在按下带有此功能的按钮时运行 VNRecognizeTextRequest
I'm trying to get the dimensions of a displayed image to draw bounding boxes over the text I have recognized using apple's Vision framework. So I run the VNRecognizeTextRequest uppon the press of a button with this funcion
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])
}
并使用此结构和函数计算边界框偏移
and compute the bounding boxes offsets using this struct and function
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 中放置矩形
I place the rects using this code in the 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)
}
}
如果我使用原始图像尺寸,我会得到这些结果
If I use the original's image dimensions I get these results
但是如果我添加
Image(nsImage: self.img!)
.resizable()
.scaledToFit()
我得到了这些结果
有没有办法获取图像尺寸并传递它们并获得所显示图像的正确尺寸?我也需要这个,因为有时我无法显示整个图像并且需要对其进行缩放.
Is there a way to get the image dimensions and pass them and get the proper size of the image being displayed? I also need this because I can't show the whole image sometimes and need to scale it.
非常感谢
推荐答案
我会在背景上使用 GeometryReader
以便它准确读取图像的大小,如下所示
I would use GeometryReader
on background so it reads exactly size of image, as below
@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))
}
}
这篇关于Swiftui 获取图像的显示尺寸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!