123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711 |
- #import "KMGOCRManager.h"
- #import <PDF_Reader_Pro-Swift.h>
- #import <Vision/VNRecognizeTextRequest.h>
- #import <Vision/VNRequestHandler.h>
- #import <Vision/VNObservation.h>
- #define KMImageScale 4.0
- NSString * KMGOCRLanguageCodeKey = @"KMGOCRLanguageCodeKey";
- NSString * KMGOCRLanguageStringKey = @"KMGOCRLanguageStringKey";
- #pragma mark - KMGOCRResult
- @class KMOCROperationQueue;
- @interface KMGOCRResult ()
- @end
- @implementation KMGOCRResult
- - (void)dealloc {
-
- }
- @end
- #pragma mark - KMGOCRManager
- @interface KMGOCRManager () <KMGOCROperationDelegate, KMOCROperationDelegate>
- @property (nonatomic, retain) NSMutableArray *languages;
- @property (nonatomic, assign) NSString *fileType;
- @property (nonatomic, retain) NSMutableArray *ocrPath;
- @property (nonatomic, retain) NSURL *filePath;
- @property (nonatomic, assign) NSUInteger finishIndex;
- @property (nonatomic,retain) VNRecognizeTextRequest *appleRequest;
- @property (nonatomic, assign) VNRequestTextRecognitionLevel appleRecognitionMode;
- @property (nonatomic,retain) NSMutableArray *images;
- @end
- @implementation KMGOCRManager
- #pragma mark - Init Methods
- - (id)init {
- if (self = [super init]) {
- }
- return self;
- }
- - (void)dealloc {
- _delegate = nil;
- if (@available(macOS 10.15, *)) {
-
- }
- }
- #pragma mark - Public Methods
- + (KMGOCRManager *)defaultManager {
- static KMGOCRManager *singleton = nil;
- static dispatch_once_t pred;
- dispatch_once(&pred, ^{
- singleton = [[KMGOCRManager alloc] init];
- });
- return singleton;
- }
- + (NSArray *)languages {
- if ([KMGOCRManager defaultManager].OCRType == KMOCRType_Google) {
- return @[@{KMGOCRLanguageCodeKey:@"af", KMGOCRLanguageStringKey:@"Afrikaans"},
- @{KMGOCRLanguageCodeKey:@"sq", KMGOCRLanguageStringKey:@"Albanian"},
- @{KMGOCRLanguageCodeKey:@"ar", KMGOCRLanguageStringKey:@"Arabic"},
- @{KMGOCRLanguageCodeKey:@"hy", KMGOCRLanguageStringKey:@"Armenian"},
- @{KMGOCRLanguageCodeKey:@"az", KMGOCRLanguageStringKey:@"Azerbaijani"},
- @{KMGOCRLanguageCodeKey:@"eu", KMGOCRLanguageStringKey:@"Basque"},
- @{KMGOCRLanguageCodeKey:@"be", KMGOCRLanguageStringKey:@"Belarusian"},
- @{KMGOCRLanguageCodeKey:@"bn", KMGOCRLanguageStringKey:@"Bengali"},
- @{KMGOCRLanguageCodeKey:@"bs", KMGOCRLanguageStringKey:@"Bosnian"},
- @{KMGOCRLanguageCodeKey:@"bg", KMGOCRLanguageStringKey:@"Bulgarian"},
- @{KMGOCRLanguageCodeKey:@"ca", KMGOCRLanguageStringKey:@"Catalan"},
- @{KMGOCRLanguageCodeKey:@"ceb", KMGOCRLanguageStringKey:@"Cebuano"},
- @{KMGOCRLanguageCodeKey:@"ny", KMGOCRLanguageStringKey:@"Chichewa"},
- @{KMGOCRLanguageCodeKey:@"zh-CN", KMGOCRLanguageStringKey:@"Chinese Simplified"},
- @{KMGOCRLanguageCodeKey:@"zh-TW", KMGOCRLanguageStringKey:@"Chinese Traditional"},
- @{KMGOCRLanguageCodeKey:@"hr", KMGOCRLanguageStringKey:@"Croatian"},
- @{KMGOCRLanguageCodeKey:@"cs", KMGOCRLanguageStringKey:@"Czech"},
- @{KMGOCRLanguageCodeKey:@"da", KMGOCRLanguageStringKey:@"Danish"},
- @{KMGOCRLanguageCodeKey:@"nl", KMGOCRLanguageStringKey:@"Dutch"},
- @{KMGOCRLanguageCodeKey:@"en", KMGOCRLanguageStringKey:@"English"},
- @{KMGOCRLanguageCodeKey:@"eo", KMGOCRLanguageStringKey:@"Esperanto"},
- @{KMGOCRLanguageCodeKey:@"et", KMGOCRLanguageStringKey:@"Estonian"},
- @{KMGOCRLanguageCodeKey:@"tl", KMGOCRLanguageStringKey:@"Filipino"},
- @{KMGOCRLanguageCodeKey:@"fi", KMGOCRLanguageStringKey:@"Finnish"},
- @{KMGOCRLanguageCodeKey:@"fr", KMGOCRLanguageStringKey:@"French"},
- @{KMGOCRLanguageCodeKey:@"gl", KMGOCRLanguageStringKey:@"Galician"},
- @{KMGOCRLanguageCodeKey:@"ka", KMGOCRLanguageStringKey:@"Georgian"},
- @{KMGOCRLanguageCodeKey:@"de", KMGOCRLanguageStringKey:@"German"},
- @{KMGOCRLanguageCodeKey:@"el", KMGOCRLanguageStringKey:@"Greek"},
- @{KMGOCRLanguageCodeKey:@"gu", KMGOCRLanguageStringKey:@"Gujarati"},
- @{KMGOCRLanguageCodeKey:@"ht", KMGOCRLanguageStringKey:@"Haitian Creole"},
- @{KMGOCRLanguageCodeKey:@"ha", KMGOCRLanguageStringKey:@"Hausa"},
- @{KMGOCRLanguageCodeKey:@"iw", KMGOCRLanguageStringKey:@"Hebrew"},
- @{KMGOCRLanguageCodeKey:@"hi", KMGOCRLanguageStringKey:@"Hindi"},
- @{KMGOCRLanguageCodeKey:@"hmn", KMGOCRLanguageStringKey:@"Hmong"},
- @{KMGOCRLanguageCodeKey:@"hu", KMGOCRLanguageStringKey:@"Hungarian"},
- @{KMGOCRLanguageCodeKey:@"is", KMGOCRLanguageStringKey:@"Icelandic"},
- @{KMGOCRLanguageCodeKey:@"ig", KMGOCRLanguageStringKey:@"Igbo"},
- @{KMGOCRLanguageCodeKey:@"id", KMGOCRLanguageStringKey:@"Indonesian"},
- @{KMGOCRLanguageCodeKey:@"ga", KMGOCRLanguageStringKey:@"Irish"},
- @{KMGOCRLanguageCodeKey:@"it", KMGOCRLanguageStringKey:@"Italian"},
- @{KMGOCRLanguageCodeKey:@"ja", KMGOCRLanguageStringKey:@"Japanese"},
- @{KMGOCRLanguageCodeKey:@"jw", KMGOCRLanguageStringKey:@"Javanese"},
- @{KMGOCRLanguageCodeKey:@"kn", KMGOCRLanguageStringKey:@"Kannada"},
- @{KMGOCRLanguageCodeKey:@"kk", KMGOCRLanguageStringKey:@"Kazakh"},
- @{KMGOCRLanguageCodeKey:@"km", KMGOCRLanguageStringKey:@"Khmer"},
- @{KMGOCRLanguageCodeKey:@"ko", KMGOCRLanguageStringKey:@"Korean"},
- @{KMGOCRLanguageCodeKey:@"lo", KMGOCRLanguageStringKey:@"Lao"},
- @{KMGOCRLanguageCodeKey:@"la", KMGOCRLanguageStringKey:@"Latin"},
- @{KMGOCRLanguageCodeKey:@"lv", KMGOCRLanguageStringKey:@"Latvian"},
- @{KMGOCRLanguageCodeKey:@"lt", KMGOCRLanguageStringKey:@"Lithuanian"},
- @{KMGOCRLanguageCodeKey:@"mk", KMGOCRLanguageStringKey:@"Macedonian"},
- @{KMGOCRLanguageCodeKey:@"mg", KMGOCRLanguageStringKey:@"Malagasy"},
- @{KMGOCRLanguageCodeKey:@"ms", KMGOCRLanguageStringKey:@"Malay"},
- @{KMGOCRLanguageCodeKey:@"ml", KMGOCRLanguageStringKey:@"Malayalam"},
- @{KMGOCRLanguageCodeKey:@"mt", KMGOCRLanguageStringKey:@"Maltese"},
- @{KMGOCRLanguageCodeKey:@"mi", KMGOCRLanguageStringKey:@"Maori"},
- @{KMGOCRLanguageCodeKey:@"mr", KMGOCRLanguageStringKey:@"Marathi"},
- @{KMGOCRLanguageCodeKey:@"mn", KMGOCRLanguageStringKey:@"Mongolian"},
- @{KMGOCRLanguageCodeKey:@"my", KMGOCRLanguageStringKey:@"Myanmar (Burmese)"},
- @{KMGOCRLanguageCodeKey:@"ne", KMGOCRLanguageStringKey:@"Nepali"},
- @{KMGOCRLanguageCodeKey:@"no", KMGOCRLanguageStringKey:@"Norwegian"},
- @{KMGOCRLanguageCodeKey:@"fa", KMGOCRLanguageStringKey:@"Persian"},
- @{KMGOCRLanguageCodeKey:@"pl", KMGOCRLanguageStringKey:@"Polish"},
- @{KMGOCRLanguageCodeKey:@"pt", KMGOCRLanguageStringKey:@"Portuguese"},
- @{KMGOCRLanguageCodeKey:@"ma", KMGOCRLanguageStringKey:@"Punjabi"},
- @{KMGOCRLanguageCodeKey:@"ro", KMGOCRLanguageStringKey:@"Romanian"},
- @{KMGOCRLanguageCodeKey:@"ru", KMGOCRLanguageStringKey:@"Russian"},
- @{KMGOCRLanguageCodeKey:@"sr", KMGOCRLanguageStringKey:@"Serbian"},
- @{KMGOCRLanguageCodeKey:@"st", KMGOCRLanguageStringKey:@"Sesotho"},
- @{KMGOCRLanguageCodeKey:@"si", KMGOCRLanguageStringKey:@"Sinhala"},
- @{KMGOCRLanguageCodeKey:@"sk", KMGOCRLanguageStringKey:@"Slovak"},
- @{KMGOCRLanguageCodeKey:@"sl", KMGOCRLanguageStringKey:@"Slovenian"},
- @{KMGOCRLanguageCodeKey:@"so", KMGOCRLanguageStringKey:@"Somali"},
- @{KMGOCRLanguageCodeKey:@"es", KMGOCRLanguageStringKey:@"Spanish"},
- @{KMGOCRLanguageCodeKey:@"su", KMGOCRLanguageStringKey:@"Sudanese"},
- @{KMGOCRLanguageCodeKey:@"sw", KMGOCRLanguageStringKey:@"Swahili"},
- @{KMGOCRLanguageCodeKey:@"sv", KMGOCRLanguageStringKey:@"Swedish"},
- @{KMGOCRLanguageCodeKey:@"tg", KMGOCRLanguageStringKey:@"Tajik"},
- @{KMGOCRLanguageCodeKey:@"ta", KMGOCRLanguageStringKey:@"Tamil"},
- @{KMGOCRLanguageCodeKey:@"te", KMGOCRLanguageStringKey:@"Telugu"},
- @{KMGOCRLanguageCodeKey:@"th", KMGOCRLanguageStringKey:@"Thai"},
- @{KMGOCRLanguageCodeKey:@"tr", KMGOCRLanguageStringKey:@"Turkish"},
- @{KMGOCRLanguageCodeKey:@"uk", KMGOCRLanguageStringKey:@"Ukrainian"},
- @{KMGOCRLanguageCodeKey:@"ur", KMGOCRLanguageStringKey:@"Urdu"},
- @{KMGOCRLanguageCodeKey:@"uz", KMGOCRLanguageStringKey:@"Uzbek"},
- @{KMGOCRLanguageCodeKey:@"vi", KMGOCRLanguageStringKey:@"Vietnamese"},
- @{KMGOCRLanguageCodeKey:@"cy", KMGOCRLanguageStringKey:@"Welsh"},
- @{KMGOCRLanguageCodeKey:@"yi", KMGOCRLanguageStringKey:@"Yiddish"},
- @{KMGOCRLanguageCodeKey:@"yo", KMGOCRLanguageStringKey:@"Yoruba"},
- @{KMGOCRLanguageCodeKey:@"zu", KMGOCRLanguageStringKey:@"Zulu"}];
- }
- return @[@{KMGOCRLanguageCodeKey:@"en-US", KMGOCRLanguageStringKey:@"English"},
- @{KMGOCRLanguageCodeKey:@"fr-FR", KMGOCRLanguageStringKey:@"French"},
- @{KMGOCRLanguageCodeKey:@"it-IT", KMGOCRLanguageStringKey:@"Italian"},
- @{KMGOCRLanguageCodeKey:@"de-DE", KMGOCRLanguageStringKey:@"German"},
- @{KMGOCRLanguageCodeKey:@"es-ES", KMGOCRLanguageStringKey:@"Spanish"},
- @{KMGOCRLanguageCodeKey:@"pt-BR", KMGOCRLanguageStringKey:@"Portuguese"},
- @{KMGOCRLanguageCodeKey:@"zh-Hant", KMGOCRLanguageStringKey:@"Chinese Traditional"},
- @{KMGOCRLanguageCodeKey:@"zh-Hans", KMGOCRLanguageStringKey:@"Chinese Simplified"}];
- }
- static inline NSFont * FontWithSize(NSString *strChar, CGSize size) {
- CGFloat fontsize = 1.0;
- NSFont *font = [NSFont systemFontOfSize:fontsize];
- CGSize strSize = [strChar sizeWithAttributes:@{NSFontAttributeName:font}];
- while ((fontsize<127) && (strSize.width<size.width || strSize.height<size.height)) {
- fontsize += 1.0;
- font = [NSFont systemFontOfSize:fontsize];
- strSize = [strChar sizeWithAttributes:@{NSFontAttributeName:font}];
- }
- return [NSFont systemFontOfSize:fontsize-1];
- }
- - (void)createPDFFile:(NSString *)filePath imagePaths:(NSArray *)paths results:(NSArray *)resultsArray scale:(CGFloat)scale {
- if (paths.count < 1) {
- return;
- }
-
- CFStringRef path = (__bridge CFStringRef)filePath;
- CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0);
- CFMutableDictionaryRef myDictionary = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("Kdan Mobile PDF Reader"));
-
- CGContextRef pdfContext = CGPDFContextCreateWithURL(url, &CGRectZero, myDictionary);
- CGContextSetRGBFillColor(pdfContext, 1.0, 0.0, 0.0, 0.0);
- CGContextSetTextDrawingMode(pdfContext, kCGTextFill);
-
- CFRelease(myDictionary);
- CFRelease(url);
-
- for (int i=0; i<paths.count; i++) {
- NSString *path = [paths objectAtIndex:i];
- NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
- CIImage *imageCIImage = [CIImage imageWithContentsOfURL:[NSURL fileURLWithPath:path]];
- NSSize size = [imageCIImage extent].size;
- CGRect pageRect = CGRectMake(0, 0, size.width/scale, size.height/scale);
-
- CFMutableDictionaryRef pageDictionary = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDataRef boxData = CFDataCreate(NULL,(const UInt8 *)&pageRect, sizeof (CGRect));
- CFDictionarySetValue(pageDictionary, kCGPDFContextMediaBox, boxData);
- CGPDFContextBeginPage (pdfContext, pageDictionary);
- NSData *imageData = [NSData dataWithContentsOfFile:path];
- CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
- CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
- CGContextSaveGState(pdfContext);
- CGContextDrawImage(pdfContext, pageRect, imageRef);
- CGContextRestoreGState(pdfContext);
- CGImageRelease(imageRef);
-
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:pdfContext flipped:NO]];
- NSArray *results = nil;
- if (i < resultsArray.count) {
- results = resultsArray[i];
- CGFloat newScale = scale;
- if([KMGOCRManager defaultManager].OCRType == KMOCRType_Apple)
- newScale = 1;
- if (results.count == 1) {
- KMGOCRResult *result = results[0];
- NSRect bounds = NSMakeRect((result.textBounds.origin.x)/newScale,
- pageRect.size.height-(result.textBounds.origin.y+result.textBounds.size.height)/newScale,
- (result.textBounds.size.width)/newScale,
- (result.textBounds.size.height)/newScale);
- NSDictionary *dic = @{NSFontAttributeName:FontWithSize(result.text, CGSizeMake(result.textBounds.size.width/newScale, result.textBounds.size.height/newScale)),
- NSForegroundColorAttributeName:[NSColor clearColor]};
- [result.text drawInRect:bounds withAttributes:dic];
- } else {
- for (int i=1; i<results.count; i++) {
- KMGOCRResult *result = results[i];
- NSRect bounds = NSMakeRect((result.textBounds.origin.x)/newScale,
- pageRect.size.height-(result.textBounds.origin.y+result.textBounds.size.height)/newScale,
- (result.textBounds.size.width)/newScale,
- (result.textBounds.size.height)/newScale);
- NSDictionary *dic = @{NSFontAttributeName:FontWithSize(result.text, CGSizeMake(result.textBounds.size.width/newScale, result.textBounds.size.height/newScale)),
- NSForegroundColorAttributeName:[NSColor clearColor]};
- [result.text drawInRect:bounds withAttributes:dic];
- }
- }
- }
- [NSGraphicsContext restoreGraphicsState];
-
- CGPDFContextEndPage (pdfContext);
-
- CFRelease(pageDictionary);
- CFRelease(boxData);
- }
-
- CGPDFContextClose(pdfContext);
- CGContextRelease (pdfContext);
- }
- - (void)recognitionImages:(NSArray *)images withLanguages:(NSArray *)languages {
- [self recognitionImages:images withLanguages:languages fileType:nil filePath:nil];
- }
- - (void)recognitionImages:(NSArray *)images withLanguages:(NSArray *)languages fileType:(NSString * _Nullable)fileType filePath:(NSURL *)filePath {
- self.ocrPath = [[NSMutableArray alloc] init];
- self.finishIndex = 0;
- self.fileType = @"PDF";
- self.images = [NSMutableArray arrayWithArray:images];
-
- if (!filePath) {
- self.filePath = [NSURL URLWithString:[NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
- } else {
- self.filePath = filePath;
- }
-
-
-
- if (self.OCRType == KMOCRType_Google) {
- [self gocrRecognitionImages:images withLanguages:languages];
- }else{
- if (@available(macOS 10.15, *)) {
- if (_appleRequest) {
- [_appleRequest cancel];
- _appleRequest = nil;
- }
- [self recognitionAppleImageAtIndex:self.finishIndex];
- } else {
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didFailureOCRImageAtIndex:error:)]) {
- [self.delegate GOCRManager:self didFailureOCRImageAtIndex:self.finishIndex error:nil];
- }
- }
- }
- }
- - (void)cancelRecognition {
- if (@available(macOS 10.15, *)) {
- if (_appleRequest) {
- [_appleRequest cancel];
- _appleRequest = nil;
- }
- }
- [self.images removeAllObjects];
- self.languages = nil;
- self.finishIndex = 0;
- KMOCROperationQueue *queue = [KMOCROperationQueue sharedInstance];
- if (queue.operations.count > 0) {
- for (KMGOCROperation *op in queue.operations) {
- op.operationDelegate = nil;
- }
- [queue cancelAll];
- }
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didCancelOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didCancelOCRImageAtIndex:self.finishIndex];
- }
- self.delegate = nil;
- }
- #pragma mark - Apple OCR
- - (void)recognitionAppleImageAtIndex:(NSUInteger)index {
- if (index >= self.images.count) {
- if (@available(macOS 10.15, *)) {
- [_appleRequest cancel];
- }
- _appleRequest = nil;
- if ([self.delegate respondsToSelector:@selector(GOCRManagerDidFinishOCR:)]) {
- [self.delegate GOCRManagerDidFinishOCR:self];
- }
- return;
- }
- self.finishIndex = index;
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didStartOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didStartOCRImageAtIndex:self.finishIndex];
- }
- if([self.images[self.finishIndex] isKindOfClass:[NSImage class]]) {
- [self recognitionAppleImage:self.images[self.finishIndex]];
- } else {
- NSData *data = self.images[self.finishIndex];
- NSImage *s = [[NSImage alloc] initWithData:data];
- if(_appleRequest) {
- [_appleRequest cancel];
- _appleRequest = nil;
- }
- [self recognitionAppleImage:s];
- }
- }
- - (void)recognitionAppleImage:(NSImage *)image {
- dispatch_async(dispatch_get_global_queue(0, 0), ^{
- __block typeof(self) blockSelf = self;
- _appleRequest = [[VNRecognizeTextRequest alloc] initWithCompletionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error) {
- NSArray *results = nil;
- if (request.results.count > 0) {
- results = [blockSelf responseDataRequest:request dictionary:nil imageSize:image.size];
- }
- NSMutableArray *resultArray = [[NSMutableArray alloc] init];
- for (KMGOCRResult *result in results) {
- NSDictionary *dic = @{@"x":@(result.textBounds.origin.x),
- @"y":@(result.textBounds.origin.y),
- @"width":@(result.textBounds.size.width),
- @"height":@(result.textBounds.size.height),
- @"text":result.text
- };
- [resultArray addObject:dic];
- }
-
- dispatch_async(dispatch_get_main_queue(), ^{
- if (error || !results) {
- if (self.delegate && [blockSelf.delegate respondsToSelector:@selector(GOCRManager:didFailureOCRImageAtIndex:error:)]) {
- [blockSelf.delegate GOCRManager:blockSelf didFailureOCRImageAtIndex:blockSelf.finishIndex error:error];
- }
- } else {
- if (self.delegate && [blockSelf.delegate respondsToSelector:@selector(GOCRManager:didFinishOCRImageAtIndex:results:)]) {
- [blockSelf.delegate GOCRManager:blockSelf didFinishOCRImageAtIndex:blockSelf.finishIndex results:results];
- }
- }
- [blockSelf recognitionAppleImageAtIndex:blockSelf.finishIndex+1];
- });
- }];
- self->_appleRequest.usesCPUOnly = YES;
- self->_appleRequest.recognitionLevel = self.appleRecognitionMode;
- if (self.languages.count > 0) {
- NSMutableArray *array = [[NSMutableArray alloc] initWithArray:blockSelf.languages];
- if ([self.languages containsObject:@"zh-Hant"]) {
- [array removeObject:@"zh-Hant"];
- [array insertObject:@"zh-Hant" atIndex:0];
- }
- if ([self.languages containsObject:@"zh-Hans"]) {
- [array removeObject:@"zh-Hans"];
- [array insertObject:@"zh-Hans" atIndex:0];
- }
- self.languages = array;
- self->_appleRequest.recognitionLanguages = self.languages;
- }else{
- self->_appleRequest.recognitionLanguages = @[@"zh-Hans",@"zh-Hant"];
- }
- NSError *error = nil;
- VNImageRequestHandler *handle = [[VNImageRequestHandler alloc] initWithCGImage:[self nsImageToCGImageRef:image] options:@{}];
- if (self->_appleRequest){
- [handle performRequests:@[self->_appleRequest] error:&error];
- }
- });
- }
- #pragma mark - GOCRManager Methods
- - (void)gocrRecognitionImages:(NSArray *)images withLanguages:(NSArray *)languages {
- if (!images || images.count == 0) {
- return;
- }
-
- if ([self.delegate respondsToSelector:@selector(GOCRManagerDidStartOCR:)]) {
- [self.delegate GOCRManagerDidStartOCR:self];
- }
-
- for (NSUInteger i=0; i<images.count; i++) {
-
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didStartOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didStartOCRImageAtIndex:i];
- }
- KMOCROperationQueue *queue = [KMOCROperationQueue sharedInstance];
- queue.maxConcurrentOperationCount = 1;
- NSImage *image = [[NSImage alloc] init];
- if([images[i] isKindOfClass:[NSImage class]]) {
- image = images[i];
- } else {
- NSData *data = images[i];
- image = [[NSImage alloc] initWithData:data];
- }
- KMGOCROperation *op = [[KMGOCROperation alloc] initWithRecognitionImg:image imgIndex:i];
- op.selectedLanguages = [NSMutableArray arrayWithArray:languages];
- op.operationDelegate = self;
- [queue addOperation:op];
- }
- }
- #pragma mark - OCRManager Methods
- - (void)ocrRecognitionImages:(NSArray *)images withLanguages:(NSArray *)languages {
- self.languages = [[NSMutableArray alloc] init];
- if (!images || images.count == 0) {
- return;
- }
-
- if (languages.count == 0) {
- for (NSDictionary *dict in [KMGOCRManager languages]) {
- [self.languages addObject:dict[KMGOCRLanguageCodeKey]];
- }
- } else {
- [self.languages addObjectsFromArray:languages];
- }
-
- for (NSUInteger i=0; i<images.count; i++) {
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didStartOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didStartOCRImageAtIndex:i];
- }
- NSString *desktopPath = [NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES) objectAtIndex:0];
- NSDateFormatter *formatter = [[NSDateFormatter alloc ] init];
- [formatter setDateFormat:@"YYYY-MM-dd-hh-mm-ss-SSS"];
- NSString *dateString = [formatter stringFromDate:[NSDate date]];
- NSString *fileName;
- if ([self.fileType isEqualToString:@"PDF"]) {
- fileName = [NSString stringWithFormat:@"%@-%ld.pdf",dateString,i];
- } else {
- fileName = [NSString stringWithFormat:@"%@-%ld.txt",dateString,i];
- }
- NSString *strPath = [desktopPath stringByAppendingPathComponent:fileName];
- [_ocrPath addObject:strPath];
-
- KMOCROperationQueue *queue = [KMOCROperationQueue sharedInstance];
- queue.maxConcurrentOperationCount = images.count;
-
- NSImage *image = [[NSImage alloc] init];
- if([images[i] isKindOfClass:[NSImage class]]) {
- image = images[i];
- } else {
- NSData *data = images[i];
- image = [[NSImage alloc] initWithData:data];
- }
-
- KMOCROperation *op = [[KMOCROperation alloc] initWithRecognitionImg:image imgIndex:i];
- op.fileType = self.fileType;
- op.selectedLanguages = self.languages;
- op.filePath = fileName;
- op.operationDelegate = self;
- [queue addOperation:op];
- }
- }
- #pragma mark - Private Methods
- - (void)setIsOCR:(BOOL)isOCR {
- _isOCR = isOCR;
- }
- - (NSString *)joinPDF:(NSArray *)listOfPaths {
-
- NSDateFormatter *formatter = [[NSDateFormatter alloc ] init];
- [formatter setDateFormat:@"YYYY-MM-dd-hh-mm-ss-SSS"];
- NSString *dateString = [formatter stringFromDate:[NSDate date]];
- NSString *fileName;
- if ([self.fileType isEqualToString:@"PDF"]) {
- fileName = [NSString stringWithFormat:@"%@.pdf",dateString];
- } else {
- fileName = [NSString stringWithFormat:@"%@.txt",dateString];
- }
-
- NSString *pdfPathOutput = [[_filePath path] stringByAppendingPathComponent:fileName];
- CFURLRef pdfURLOutput = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:pdfPathOutput]);
- NSInteger numberOfPages = 0;
- CGContextRef writeContext = CGPDFContextCreateWithURL(pdfURLOutput, NULL, NULL);
- for (NSString *source in listOfPaths) {
- CFURLRef pdfURL = (CFURLRef)CFBridgingRetain([[NSURL alloc] initFileURLWithPath:source]);
- CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
- numberOfPages = CGPDFDocumentGetNumberOfPages(pdfRef);
- CGPDFPageRef page;
- CGRect mediaBox;
- for (int i=1; i<=numberOfPages; i++) {
- page = CGPDFDocumentGetPage(pdfRef, i);
- mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
- CGContextBeginPage(writeContext, &mediaBox);
- CGContextDrawPDFPage(writeContext, page);
- CGContextEndPage(writeContext);
- }
- CGPDFDocumentRelease(pdfRef);
- CFRelease(pdfURL);
- }
- CFRelease(pdfURLOutput);
- CGPDFContextClose(writeContext);
- CGContextRelease(writeContext);
-
- if ([self.delegate respondsToSelector:@selector(GOCRManagerDidFinishOCR:)]) {
- [self.delegate GOCRManagerDidFinishOCR:self];
- }
- NSLog(@"pdfPathOutput == %@",pdfPathOutput);
- return pdfPathOutput;
- }
- #pragma mark - KMOCROperationDelegate
- - (void)OCROperation:(KMOCROperation *)operation startOCRImageAtIndex:(NSInteger)index {
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didStartOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didStartOCRImageAtIndex:index];
- }
- }
- - (void)OCROperation:(KMOCROperation *)operation cancelOCRImageAtIndex:(NSInteger)index {
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didCancelOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didCancelOCRImageAtIndex:index];
- }
- }
- - (void)OCROperation:(KMOCROperation *)operation finishOCRImageAtIndex:(NSInteger)index results:(NSArray *)result {
- self.finishIndex++;
-
- if ([self.delegate respondsToSelector:@selector(CHOCRManager:didFinishOCRImageAtIndex:results:)]) {
- [self.delegate CHOCRManager:self didFinishOCRImageAtIndex:_finishIndex results:result];
- }
- }
- - (void)OCROperation:(KMOCROperation *)operation failureOCRImageAtIndex:(NSInteger)index error:(NSError *)error {
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didFailureOCRImageAtIndex:error:)]) {
- [self.delegate GOCRManager:self didFailureOCRImageAtIndex:index error:error];
- }
- }
- #pragma mark - KMGOCROperationDelegate
- - (void)GOCROperation:(KMGOCROperation *)operation startOCRImageAtIndex:(NSInteger)index{
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didStartOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didStartOCRImageAtIndex:index];
- }
- }
- - (void)GOCROperation:(KMGOCROperation *)operation cancelOCRImageAtIndex:(NSInteger)index{
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didCancelOCRImageAtIndex:)]) {
- [self.delegate GOCRManager:self didCancelOCRImageAtIndex:index];
- }
- }
- - (void)GOCROperation:(KMGOCROperation *)operation finishOCRImageAtIndex:(NSInteger)index results:(NSArray *)results {
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didFinishOCRImageAtIndex:results:)]) {
- [self.delegate GOCRManager:self didFinishOCRImageAtIndex:index results:results];
- }
- self.finishIndex++;
- if(self.finishIndex == self.images.count) {
- if ([self.delegate respondsToSelector:@selector(GOCRManagerDidFinishOCR:)]) {
- [self.delegate GOCRManagerDidFinishOCR:self];
- }
- }
- }
- - (void)GOCROperation:(KMGOCROperation *)operation failureOCRImageAtIndex:(NSInteger)index error:(NSError *)error {
- if ([self.delegate respondsToSelector:@selector(GOCRManager:didFailureOCRImageAtIndex:error:)]) {
- [self.delegate GOCRManager:self didFailureOCRImageAtIndex:index error:error];
- }
- self.finishIndex++;
- }
- - (NSArray *)responseDataRequest:(VNRequest *)request dictionary:(NSDictionary *)dictionary imageSize:(CGSize)imageSize{
- NSMutableArray *results = [NSMutableArray array];
- NSInteger maximumCandidates = 1;
- NSString *OCRStr = @"";
-
- if (request) {
- for (VNRecognizedTextObservation *observation in request.results) {
- VNRecognizedText *text = [observation topCandidates:maximumCandidates].firstObject;
-
- OCRStr = [OCRStr stringByAppendingString:[NSString stringWithFormat:@"%@\n",text.string]];
-
- NSError *error = nil;
- VNRectangleObservation *rectangleObservation = [text boundingBoxForRange:NSMakeRange(0, text.string.length) error:&error];
- CGFloat x = 0, y = 0, width = 0, height = 0;
- x = rectangleObservation.topLeft.x * imageSize.width;
- y = (1 - rectangleObservation.topLeft.y) * imageSize.height;
- width = rectangleObservation.boundingBox.size.width * imageSize.width;
- height = rectangleObservation.boundingBox.size.height * imageSize.height;
-
- KMGOCRResult *result = [[KMGOCRResult alloc] init];
- result.text = text.string;
- result.locale = @"";
- result.textBounds = CGRectMake(x, y, width, height);
- [results addObject:result];
- }
-
- if (results.count > 0) {
- KMGOCRResult *result = [[KMGOCRResult alloc] init];
- result.text = OCRStr;
- if (self.languages.count > 0) {
- result.locale = self.languages[0];
- }
- result.textBounds = CGRectZero;
- [results insertObject:result atIndex:0];
- }
- }
- return results;
- }
- - (CGImageRef)nsImageToCGImageRef:(NSImage*)image;
- {
- NSData * imageData = [image TIFFRepresentation];
- CGImageRef imageRef;
- if(imageData)
- {
- CGImageSourceRef imageSource =
- CGImageSourceCreateWithData(
- (CFDataRef)imageData, NULL);
- imageRef = CGImageSourceCreateImageAtIndex(
- imageSource, 0, NULL);
- }
- return imageRef;
- }
- @end
- @interface KMOCROperationQueue ()
- @end
- @implementation KMOCROperationQueue
- - (void)dealloc {
-
- }
- + (instancetype)sharedInstance {
- static KMOCROperationQueue *sharedInstance;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- sharedInstance = [KMOCROperationQueue new];
- });
- return sharedInstance;
- }
- - (void)addOCROperation:(NSOperation *)op {
- [self addOperation:op];
- }
- - (void)cancelAll {
- [self cancelAllOperations];
- }
- @end
|