fix: provide a software image context for OCR compatibility
This commit is contained in:
1 parent
b22eaf9715
commit
ff576ad166
4 files changed
+34
-7
No files matched your search
Generated
+1
@@ -4472,6 +4472,7 @@ dependencies = [
|
||||
"objc2-app-kit",
|
||||
"objc2-core-foundation",
|
||||
"objc2-core-graphics",
|
||||
"objc2-core-image",
|
||||
"objc2-core-ml",
|
||||
"objc2-foundation",
|
||||
"objc2-image-io",
|
||||
|
||||
@@ -38,6 +38,7 @@ core-foundation = "0.10"
|
||||
security-framework = "3"
|
||||
objc2 = "0.6"
|
||||
objc2-core-foundation = "0.3"
|
||||
objc2-core-image = { version = "0.3", features = ["CIContext"] }
|
||||
objc2-core-ml = { version = "0.3", features = ["MLCPUComputeDevice", "MLComputeDeviceProtocol"] }
|
||||
objc2-image-io = { version = "0.3", features = ["CGImageSource"] }
|
||||
objc2-app-kit = { version = "0.3", features = [
|
||||
@@ -60,6 +61,7 @@ objc2-foundation = { version = "0.3", features = [
|
||||
"NSDictionary",
|
||||
"NSError",
|
||||
"NSObject",
|
||||
"NSValue",
|
||||
] }
|
||||
objc2-vision = { version = "0.3", features = [
|
||||
"objc2-core-graphics",
|
||||
|
||||
@@ -3,6 +3,7 @@ import Foundation
|
||||
import ImageIO
|
||||
import Vision
|
||||
import CoreML
|
||||
import CoreImage
|
||||
|
||||
let file = URL(fileURLWithPath: CommandLine.arguments[1])
|
||||
let data = try Data(contentsOf: file)
|
||||
@@ -51,15 +52,20 @@ let profiles: [(String, (VNRecognizeTextRequest) throws -> Void)] = [
|
||||
}),
|
||||
]
|
||||
for (name, configure) in profiles {
|
||||
for software in [false, true] {
|
||||
do {
|
||||
let request = VNRecognizeTextRequest()
|
||||
try configure(request)
|
||||
let handler = VNImageRequestHandler(cgImage: image, options: [:])
|
||||
let options: [VNImageOption: Any] = software
|
||||
? [.ciContext: CIContext(options: [.useSoftwareRenderer: true])]
|
||||
: [:]
|
||||
let handler = VNImageRequestHandler(cgImage: image, options: options)
|
||||
try handler.perform([request])
|
||||
let text = request.results?.compactMap { $0.topCandidates(1).first?.string }.joined(separator: "\n") ?? ""
|
||||
print("\(name): OK \(text)")
|
||||
print("\(name) software=\(software): OK \(text)")
|
||||
} catch {
|
||||
let error = error as NSError
|
||||
print("\(name): ERROR domain=\(error.domain) code=\(error.code) details=\(error.userInfo)")
|
||||
print("\(name) software=\(software): ERROR domain=\(error.domain) code=\(error.code) details=\(error.userInfo)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,15 @@
|
||||
#![cfg(target_os = "macos")]
|
||||
|
||||
use objc2::rc::{autoreleasepool, Retained};
|
||||
use objc2::{AnyThread, ClassType};
|
||||
use objc2::{AnyObject, AnyThread, ClassType};
|
||||
use objc2_core_graphics::CGImage;
|
||||
use objc2_core_image::{kCIContextUseSoftwareRenderer, CIContext};
|
||||
use objc2_core_ml::MLCPUComputeDevice;
|
||||
use objc2_foundation::{NSArray, NSObjectProtocol, NSString};
|
||||
use objc2_vision::{VNImageRequestHandler, VNRecognizeTextRequest, VNRequestTextRecognitionLevel};
|
||||
use objc2_foundation::{NSArray, NSDictionary, NSNumber, NSObjectProtocol, NSString};
|
||||
use objc2_vision::{
|
||||
VNImageOptionCIContext, VNImageRequestHandler, VNRecognizeTextRequest,
|
||||
VNRequestTextRecognitionLevel,
|
||||
};
|
||||
|
||||
/// 对指定图片文件路径执行 OCR,返回识别文本(按行拼接)。
|
||||
pub fn recognize_file(path: &str) -> Result<String, String> {
|
||||
@@ -46,11 +50,25 @@ pub(super) fn recognize_once(image: &CGImage, compatibility: bool) -> Result<Str
|
||||
let request: Retained<VNRecognizeTextRequest> = VNRecognizeTextRequest::new();
|
||||
configure_request(&request, compatibility)?;
|
||||
|
||||
let options = if compatibility || objc2::available!(macos = 27.0) {
|
||||
let software = NSNumber::numberWithBool(true);
|
||||
let values: [&AnyObject; 1] = [&software];
|
||||
let context_options =
|
||||
NSDictionary::from_slices(&[kCIContextUseSoftwareRenderer], &values);
|
||||
let context = CIContext::contextWithOptions(Some(&context_options));
|
||||
let values: [&AnyObject; 1] = [&context];
|
||||
// CPU 模型选择不控制图像缩放器。显式软件 CIContext 避开
|
||||
// 新系统后台/虚拟环境中不可用的硬件图像处理路径。
|
||||
NSDictionary::from_slices(&[VNImageOptionCIContext], &values)
|
||||
} else {
|
||||
NSDictionary::new()
|
||||
};
|
||||
|
||||
// 直接提供已规范化的 CGImage,避免 Vision 再走压缩数据解码路径。
|
||||
let handler = VNImageRequestHandler::initWithCGImage_options(
|
||||
VNImageRequestHandler::alloc(),
|
||||
image,
|
||||
&objc2_foundation::NSDictionary::new(),
|
||||
&options,
|
||||
);
|
||||
|
||||
let requests = NSArray::from_retained_slice(&[Retained::into_super(Retained::into_super(
|
||||
|
||||
Reference in new issue
Block a user