diff --git a/README.md b/README.md index 0bd439b..c6ea846 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This has been tested with Python 3.11. Newer/older versions might work. It can b - [EasyOCR](https://github.com/JaidedAI/EasyOCR): refer to the readme for installation ("e" key) - [RapidOCR](https://github.com/RapidAI/RapidOCR): refer to the readme for installation ("r" key) - Apple Vision framework: this will work on macOS Ventura or later. In my experience, the best of the local providers for horizontal text ("a" key) -- Apple Live Text (VisionKit framework): this will work on macOS Ventura or later. It should be the same as Vision except that in Sonoma Apple added vertical text reading, on the other hand it's a bit slower/requires a small Swift helper tool to be downloaded (source code is in this repo, it's a stripped down version of LiTeX). ("d" key) +- Apple Live Text (VisionKit framework): this will work on macOS Ventura or later. It should be the same as Vision except that in Sonoma Apple added vertical text reading ("d" key) - WinRT OCR: this will work on Windows 10 or later if winocr (`pip install winocr`) is installed. It can also be used by installing winocr on a Windows virtual machine and running the server (`winocr_serve`), installing requests (`pip install requests`) and specifying the IP address of the Windows VM/machine in the config file (see below) ("w" key) ## Cloud providers @@ -40,9 +40,9 @@ However: # Acknowledgments This uses code from/references these projects: -- Viola for working on the Google Lens implementation and helping with the (shelved) pyobjc VisionKit code! +- Viola for working on the Google Lens implementation and helping with the pyobjc VisionKit code! +- @ronaldoussoren for helping with the pyobjc VisionKit code - [Manga OCR](https://github.com/kha-white/manga-ocr) - [ocrmac](https://github.com/straussmaximilian/ocrmac) for the Apple Vision framework API - [NadeOCR](https://github.com/Natsume-197/NadeOCR) for the Google Vision API -- [ccylin2000_lipboard_monitor](https://github.com/vaimalaviya1233/ccylin2000_lipboard_monitor) for the Windows clipboard polling code -- [LiTeX](https://github.com/Shakshi3104/LiTeX) for the Swift Live Text helper \ No newline at end of file +- [ccylin2000_lipboard_monitor](https://github.com/vaimalaviya1233/ccylin2000_lipboard_monitor) for the Windows clipboard polling code \ No newline at end of file diff --git a/livetexthelper b/livetexthelper deleted file mode 100755 index 6ff53cd..0000000 Binary files a/livetexthelper and /dev/null differ diff --git a/livetexthelper_src/LICENSE b/livetexthelper_src/LICENSE deleted file mode 100644 index 8371b76..0000000 --- a/livetexthelper_src/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Shakshi3104 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/livetexthelper_src/LiTeX/LiveTextCLI.swift b/livetexthelper_src/LiTeX/LiveTextCLI.swift deleted file mode 100644 index 3483910..0000000 --- a/livetexthelper_src/LiTeX/LiveTextCLI.swift +++ /dev/null @@ -1,58 +0,0 @@ -import Foundation -import Cocoa -import VisionKit - -class StandardError: TextOutputStream { - func write(_ string: String) { - try! FileHandle.standardError.write(contentsOf: Data(string.utf8)) - } -} - -@main -struct Litex { - static var stderr = StandardError() - - static func main() async throws { - try? await recognize() - } - - static func recognize() async throws { - if #available(macOS 13.0, *) { - if let inputData = try? FileHandle.standardInput.readToEnd() { - if let image = NSImage(data: inputData) { - try? await recognizeTextByLiveText(inputimage: image) - } - } - } - } - - @available(macOS 13, *) - static func recognizeTextByLiveText(inputimage: NSImage) async throws { - // if not supported - if !ImageAnalyzer.isSupported { - print("Live Text is not supported", to: &stderr) - return - } - - // setup ImageAnalyzer - var configuration = ImageAnalyzer.Configuration([.text]) - configuration.locales = ["ja","en"] - let analyzer = ImageAnalyzer() - - // analyze the image - let analysis = try? await analyzer.analyze(inputimage, - orientation: .up, - configuration: configuration) - // output results - if let analysis { - if analysis.hasResults(for: .text) { - print(analysis.transcript) - } else { - print("") - } - } - else { - print("Unknown error", to: &stderr) - } - } -} diff --git a/livetexthelper_src/litex.xcodeproj/project.pbxproj b/livetexthelper_src/litex.xcodeproj/project.pbxproj deleted file mode 100644 index 1359e6c..0000000 --- a/livetexthelper_src/litex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,293 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 56; - objects = { - -/* Begin PBXBuildFile section */ - CE68ABB5291F4FD1005BB9AC /* LiveTextCLI.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE68ABB4291F4FD1005BB9AC /* LiveTextCLI.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - CE68ABAF291F4FD1005BB9AC /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - CE68ABB4291F4FD1005BB9AC /* LiveTextCLI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveTextCLI.swift; sourceTree = ""; }; - D0F42AE62B784EC3006834AE /* litex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = litex; path = /Users/aurora/LiTeX/build/Debug/litex; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - CE68ABAE291F4FD1005BB9AC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - CE68ABA8291F4FD1005BB9AC = { - isa = PBXGroup; - children = ( - CE68ABB3291F4FD1005BB9AC /* LiTeX */, - ); - sourceTree = ""; - }; - CE68ABB3291F4FD1005BB9AC /* LiTeX */ = { - isa = PBXGroup; - children = ( - CE68ABB4291F4FD1005BB9AC /* LiveTextCLI.swift */, - ); - path = LiTeX; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - CE68ABB0291F4FD1005BB9AC /* litex */ = { - isa = PBXNativeTarget; - buildConfigurationList = CE68ABB8291F4FD1005BB9AC /* Build configuration list for PBXNativeTarget "litex" */; - buildPhases = ( - CE68ABAD291F4FD1005BB9AC /* Sources */, - CE68ABAE291F4FD1005BB9AC /* Frameworks */, - CE68ABAF291F4FD1005BB9AC /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = litex; - packageProductDependencies = ( - ); - productName = LiveTextPlayground; - productReference = D0F42AE62B784EC3006834AE /* litex */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - CE68ABA9291F4FD1005BB9AC /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1410; - LastUpgradeCheck = 1520; - TargetAttributes = { - CE68ABB0291F4FD1005BB9AC = { - CreatedOnToolsVersion = 14.1; - }; - }; - }; - buildConfigurationList = CE68ABAC291F4FD1005BB9AC /* Build configuration list for PBXProject "litex" */; - compatibilityVersion = "Xcode 14.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = CE68ABA8291F4FD1005BB9AC; - packageReferences = ( - ); - productRefGroup = CE68ABA8291F4FD1005BB9AC; - projectDirPath = ""; - projectRoot = ""; - targets = ( - CE68ABB0291F4FD1005BB9AC /* litex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - CE68ABAD291F4FD1005BB9AC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CE68ABB5291F4FD1005BB9AC /* LiveTextCLI.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - CE68ABB6291F4FD1005BB9AC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 13.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - CE68ABB7291F4FD1005BB9AC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 13.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = RELEASE; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - CE68ABB9291F4FD1005BB9AC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = LUZK6JBS9B; - ENABLE_HARDENED_RUNTIME = YES; - MACOSX_DEPLOYMENT_TARGET = 12.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - CE68ABBA291F4FD1005BB9AC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = LUZK6JBS9B; - ENABLE_HARDENED_RUNTIME = YES; - MACOSX_DEPLOYMENT_TARGET = 12.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - CE68ABAC291F4FD1005BB9AC /* Build configuration list for PBXProject "litex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CE68ABB6291F4FD1005BB9AC /* Debug */, - CE68ABB7291F4FD1005BB9AC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - CE68ABB8291F4FD1005BB9AC /* Build configuration list for PBXNativeTarget "litex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CE68ABB9291F4FD1005BB9AC /* Debug */, - CE68ABBA291F4FD1005BB9AC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = CE68ABA9291F4FD1005BB9AC /* Project object */; -} diff --git a/livetexthelper_src/litex.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/livetexthelper_src/litex.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/livetexthelper_src/litex.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/livetexthelper_src/litex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/livetexthelper_src/litex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/livetexthelper_src/litex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/livetexthelper_src/litex.xcodeproj/xcshareddata/xcschemes/LiveTextPlayground.xcscheme b/livetexthelper_src/litex.xcodeproj/xcshareddata/xcschemes/LiveTextPlayground.xcscheme deleted file mode 100644 index 1bc6fda..0000000 --- a/livetexthelper_src/litex.xcodeproj/xcshareddata/xcschemes/LiveTextPlayground.xcscheme +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/livetexthelper_src/litex.xcodeproj/xcshareddata/xcschemes/Release.xcscheme b/livetexthelper_src/litex.xcodeproj/xcshareddata/xcschemes/Release.xcscheme deleted file mode 100644 index e2c46ec..0000000 --- a/livetexthelper_src/litex.xcodeproj/xcshareddata/xcschemes/Release.xcscheme +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/owocr/ocr.py b/owocr/ocr.py index 243dff4..5db54b5 100644 --- a/owocr/ocr.py +++ b/owocr/ocr.py @@ -22,7 +22,8 @@ except ImportError: try: import Vision import objc - from subprocess import Popen, PIPE, STDOUT + from AppKit import NSData, NSImage, NSBundle + from PyObjCTools.AppHelper import runConsoleEventLoop, stopEventLoop except ImportError: pass @@ -280,12 +281,10 @@ class AppleVision: if success[0]: for result in req.results(): res += result.text() + '\n' - req.dealloc() x = (True, res) else: x = (False, 'Unknown error!') - handler.dealloc() return x def _preprocess(self, img): @@ -300,24 +299,41 @@ class AppleLiveText: def __init__(self): if sys.platform != 'darwin': - logger.warning('Apple Vision is not supported on non-macOS platforms!') + logger.warning('Apple Live Text is not supported on non-macOS platforms!') elif int(platform.mac_ver()[0].split('.')[0]) < 13: - logger.warning('Apple Vision is not supported on macOS older than Ventura/13.0!') + logger.warning('Apple Live Text is not supported on macOS older than Ventura/13.0!') else: - self.helper_executable = os.path.join(os.path.expanduser('~'),'.cache','livetexthelper') - if not os.path.isfile(self.helper_executable): - logger.info('Downloading helper executable ' + self.helper_executable) - try: - cache_folder = os.path.join(os.path.expanduser('~'),'.cache') - if not os.path.isdir(cache_folder): - os.makedirs(cache_folder) - urllib.request.urlretrieve('https://github.com/AuroraWright/owocr/raw/master/livetexthelper', self.helper_executable) - mode = os.stat(self.helper_executable).st_mode - mode |= (mode & 0o444) >> 2 - os.chmod(self.helper_executable, mode) - except: - logger.warning('Download failed. Apple Live Text will not work!') - return + objc.loadBundle('VisionKit', globals(), '/System/Library/Frameworks/VisionKit.framework') + objc.registerMetaDataForSelector( + b'VKCImageAnalyzer', + b'processRequest:progressHandler:completionHandler:', + { + 'arguments': { + 3: { + 'callable': { + 'retval': {'type': b'v'}, + 'arguments': { + 0: {'type': b'^v'}, + 1: {'type': b'd'}, + } + } + }, + 4: { + 'callable': { + 'retval': {'type': b'v'}, + 'arguments': { + 0: {'type': b'^v'}, + 1: {'type': b'@'}, + 2: {'type': b'@'}, + } + } + } + } + } + ) + app_info = NSBundle.mainBundle().infoDictionary() + app_info['LSBackgroundOnly'] = '1' + self.analyzer = VKCImageAnalyzer.alloc().init() self.available = True logger.info('Apple Live Text ready') @@ -329,15 +345,30 @@ class AppleLiveText: else: raise ValueError(f'img_or_path must be a path or PIL.Image, instead got: {img_or_path}') - process = Popen([self.helper_executable], stdout=PIPE, stdin=PIPE, stderr=PIPE) - stdout, stderr = process.communicate(input=self._preprocess(img)) - stdout = stdout.decode().rstrip() - if stdout == '': - return (False, stderr.decode().rstrip()) - return (True, stdout) + req = VKCImageAnalyzerRequest.alloc().initWithImage_requestType_(self._preprocess(img), 1) + req.setLocales_(['ja','en']) + self.result = None + self.analyzer.processRequest_progressHandler_completionHandler_(req, lambda progress: None, self._process) + runConsoleEventLoop() + + if not self.result: + return (False, 'Unknown error!') + return (True, self.result) + + def _process(self, analysis, error): + res = '' + lines = analysis.allLines() + if lines: + for line in lines: + res += line.string() + '\n' + self.result = res + stopEventLoop() def _preprocess(self, img): - return pil_image_to_bytes(img, 'tiff') + image_bytes = pil_image_to_bytes(img, 'tiff') + ns_data = NSData.dataWithBytes_length_(image_bytes, len(image_bytes)) + ns_image = NSImage.alloc().initWithData_(ns_data) + return ns_image class WinRTOCR: