KMOCTool.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. //
  2. // KMOCTool.m
  3. // PDF Reader Pro
  4. //
  5. // Created by liujiajie on 2023/11/15.
  6. //
  7. #import "KMOCTool.h"
  8. #import <Foundation/Foundation.h>
  9. #import <PDF_Reader_Pro-Swift.h>
  10. @implementation KMOCTool
  11. + (void)createPDFFile:(NSString *)filePath imagePaths:(NSArray *)paths results:(NSArray *)resultsArray scale:(CGFloat)scale {
  12. if (paths.count < 1) {
  13. return;
  14. }
  15. CFStringRef path = (__bridge CFStringRef)filePath;
  16. CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0);
  17. CFMutableDictionaryRef myDictionary = CFDictionaryCreateMutable(NULL,
  18. 0,
  19. &kCFTypeDictionaryKeyCallBacks,
  20. &kCFTypeDictionaryValueCallBacks);
  21. CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("Kdan Mobile PDF Reader"));
  22. CGContextRef pdfContext = CGPDFContextCreateWithURL(url, &CGRectZero, myDictionary);
  23. CGContextSetRGBFillColor(pdfContext, 1.0, 0.0, 0.0, 0.0);
  24. CGContextSetTextDrawingMode(pdfContext, kCGTextFill);
  25. CFRelease(myDictionary);
  26. CFRelease(url);
  27. for (int i=0; i<paths.count; i++) {
  28. NSString *path = [paths objectAtIndex:i];
  29. NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
  30. CIImage *imageCIImage = [CIImage imageWithContentsOfURL:[NSURL fileURLWithPath:path]];
  31. NSSize size = [imageCIImage extent].size;
  32. CGRect pageRect = CGRectMake(0, 0, size.width/scale, size.height/scale);
  33. CFMutableDictionaryRef pageDictionary = CFDictionaryCreateMutable(NULL,
  34. 0,
  35. &kCFTypeDictionaryKeyCallBacks,
  36. &kCFTypeDictionaryValueCallBacks);
  37. CFDataRef boxData = CFDataCreate(NULL,(const UInt8 *)&pageRect, sizeof (CGRect));
  38. CFDictionarySetValue(pageDictionary, kCGPDFContextMediaBox, boxData);
  39. CGPDFContextBeginPage (pdfContext, pageDictionary);
  40. NSData *imageData = [NSData dataWithContentsOfFile:path];
  41. CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
  42. CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
  43. CGContextSaveGState(pdfContext);
  44. CGContextDrawImage(pdfContext, pageRect, imageRef);
  45. CGContextRestoreGState(pdfContext);
  46. CGImageRelease(imageRef);
  47. [NSGraphicsContext saveGraphicsState];
  48. [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:pdfContext flipped:NO]];
  49. NSArray *results = nil;
  50. if (i < resultsArray.count) {
  51. results = resultsArray[i];
  52. CGFloat newScale = scale;
  53. if([KMGOCRManager defaultManager].OCRType == KMOCRType_Apple)
  54. newScale = 1;
  55. if (results.count == 1) {
  56. KMGOCRResult *result = results[0];
  57. NSRect bounds = NSMakeRect((result.textBounds.origin.x)/newScale,
  58. pageRect.size.height-(result.textBounds.origin.y+result.textBounds.size.height)/newScale,
  59. (result.textBounds.size.width)/newScale,
  60. (result.textBounds.size.height)/newScale);
  61. NSDictionary *dic = @{NSFontAttributeName:FontWithSize(result.text, CGSizeMake(result.textBounds.size.width/newScale, result.textBounds.size.height/newScale)),
  62. NSForegroundColorAttributeName:[NSColor clearColor]};
  63. [result.text drawInRect:bounds withAttributes:dic];
  64. } else {
  65. for (int i=1; i<results.count; i++) {
  66. KMGOCRResult *result = results[i];
  67. NSRect bounds = NSMakeRect((result.textBounds.origin.x)/newScale,
  68. pageRect.size.height-(result.textBounds.origin.y+result.textBounds.size.height)/newScale,
  69. (result.textBounds.size.width)/newScale,
  70. (result.textBounds.size.height)/newScale);
  71. NSDictionary *dic = @{NSFontAttributeName:FontWithSize(result.text, CGSizeMake(result.textBounds.size.width/newScale, result.textBounds.size.height/newScale)),
  72. NSForegroundColorAttributeName:[NSColor clearColor]};
  73. [result.text drawInRect:bounds withAttributes:dic];
  74. }
  75. }
  76. }
  77. [NSGraphicsContext restoreGraphicsState];
  78. CGPDFContextEndPage (pdfContext);
  79. CFRelease(pageDictionary);
  80. CFRelease(boxData);
  81. image = nil;
  82. }
  83. CGPDFContextClose(pdfContext);
  84. CGContextRelease (pdfContext);
  85. }
  86. + (CGRect)localCropRectForWindow:(CGWindowID)wNumber withBounds:(CGRect)bounds{
  87. CFArrayRef tarray = CGWindowListCreate(kCGWindowListOptionOnScreenOnly,
  88. (CGWindowID)wNumber);
  89. CFArrayRef array = CGWindowListCreateDescriptionFromArray(tarray);
  90. CFRelease(tarray);
  91. CGRect cropRect = bounds;
  92. for (NSDictionary *windowInfo in CFBridgingRelease(array)) {
  93. if ([windowInfo[(__bridge NSString*)kCGWindowNumber] integerValue] == wNumber) {
  94. NSDictionary *rectInfo = windowInfo[(__bridge NSString*)kCGWindowBounds];
  95. NSScreen *mainScreen = nil;
  96. for (NSScreen *screen in [NSScreen screens]) {
  97. if (CGPointEqualToPoint(screen.frame.origin, CGPointZero))
  98. mainScreen = screen;
  99. }
  100. CGPoint center = CGPointMake([rectInfo[@"X"] floatValue] + [rectInfo[@"Width"] floatValue]/2,
  101. mainScreen.frame.size.height - [rectInfo[@"Y"] floatValue] - [rectInfo[@"Height"] floatValue]/2);
  102. NSScreen *curScreen = nil;
  103. for (NSScreen *screen in [NSScreen screens]) {
  104. if (CGRectContainsPoint(screen.frame, center)) {
  105. curScreen = screen;
  106. break;
  107. }
  108. }
  109. if (!curScreen) {
  110. center = CGPointMake([rectInfo[@"X"] floatValue],
  111. mainScreen.frame.size.height - [rectInfo[@"Y"] floatValue]);
  112. for (NSScreen *screen in [NSScreen screens]) {
  113. if (CGRectContainsPoint(screen.frame, center)) {
  114. curScreen = screen;
  115. break;
  116. }
  117. }
  118. if (!curScreen) {
  119. center = CGPointMake([rectInfo[@"X"] floatValue] + [rectInfo[@"Width"] floatValue],
  120. mainScreen.frame.size.height - [rectInfo[@"Y"] floatValue]);
  121. for (NSScreen *screen in [NSScreen screens]) {
  122. if (CGRectContainsPoint(screen.frame, center)) {
  123. curScreen = screen;
  124. break;
  125. }
  126. }
  127. }
  128. }
  129. if (curScreen) {
  130. float y = mainScreen.frame.size.height - [rectInfo[@"Y"] floatValue] - curScreen.frame.origin.y;
  131. cropRect = CGRectMake([rectInfo[@"X"] floatValue] - curScreen.frame.origin.x,
  132. y - [rectInfo[@"Height"] floatValue],
  133. [rectInfo[@"Width"] floatValue],
  134. [rectInfo[@"Height"] floatValue]);
  135. }else {
  136. }
  137. break;
  138. }
  139. }
  140. return cropRect;
  141. }
  142. +(NSData*)convertStringsToPDFWithString:(NSArray *)strings{
  143. return convertStringsToPDF(strings);
  144. }
  145. static inline NSFont * FontWithSize(NSString *strChar, CGSize size) {
  146. CGFloat fontsize = 1.0;
  147. NSFont *font = [NSFont systemFontOfSize:fontsize];
  148. CGSize strSize = [strChar sizeWithAttributes:@{NSFontAttributeName:font}];
  149. while ((fontsize<127) && (strSize.width<size.width || strSize.height<size.height)) {
  150. fontsize += 1.0;
  151. font = [NSFont systemFontOfSize:fontsize];
  152. strSize = [strChar sizeWithAttributes:@{NSFontAttributeName:font}];
  153. }
  154. return [NSFont systemFontOfSize:fontsize-1];
  155. }
  156. static NSData *convertStringsToPDF(NSArray<NSAttributedString *> *strings)
  157. {
  158. NSMutableData *pdfData = [[NSMutableData alloc] init];
  159. CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)pdfData);
  160. CFMutableDictionaryRef myDictionary = CFDictionaryCreateMutable(NULL,
  161. 0,
  162. &kCFTypeDictionaryKeyCallBacks,
  163. &kCFTypeDictionaryValueCallBacks);
  164. CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("PDF Reader Pro"));
  165. CGRect mediaBox = CGRectMake(0, 0, 595, 842);
  166. CGContextRef pdfContext = CGPDFContextCreate(consumer, &mediaBox, myDictionary);
  167. CGContextSetRGBFillColor(pdfContext, 1.0, 0.0, 0.0, 0.0);
  168. CGContextSetTextDrawingMode(pdfContext, kCGTextFill);
  169. CFRelease(myDictionary);
  170. for (NSAttributedString *attributeString in strings) {
  171. if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_10) {
  172. NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributeString];
  173. NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
  174. [textStorage addLayoutManager:layoutManager];
  175. while (YES) {
  176. NSSize contentSize = NSMakeSize(mediaBox.size.width-40,
  177. mediaBox.size.height-40);
  178. NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:contentSize];
  179. [layoutManager addTextContainer:textContainer];
  180. NSRange rang = [layoutManager glyphRangeForTextContainer:textContainer];
  181. if (rang.length <= 0 ||
  182. rang.length + rang.location > attributeString.length) {
  183. break;
  184. }
  185. NSAttributedString *attStr = [attributeString attributedSubstringFromRange:rang];
  186. [NSGraphicsContext saveGraphicsState];
  187. // [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:pdfContext flipped:NO]];
  188. [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:pdfContext flipped:NO]];
  189. CGContextBeginPage(pdfContext, &mediaBox);
  190. [attStr drawInRect:CGRectMake(20, 20,
  191. mediaBox.size.width-40,
  192. mediaBox.size.height-40)];
  193. CGContextEndPage(pdfContext);
  194. [NSGraphicsContext restoreGraphicsState];
  195. }
  196. } else {
  197. [NSGraphicsContext saveGraphicsState];
  198. [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:pdfContext flipped:NO]];
  199. CGContextBeginPage(pdfContext, &mediaBox);
  200. [attributeString drawInRect:CGRectMake(20, 20,
  201. mediaBox.size.width-40,
  202. mediaBox.size.height-40)];
  203. CGContextEndPage(pdfContext);
  204. [NSGraphicsContext restoreGraphicsState];
  205. }
  206. }
  207. CGPDFContextClose(pdfContext);
  208. CGContextRelease (pdfContext);
  209. return pdfData;
  210. }
  211. @end