KMNThumbnailManager.swift 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //
  2. // KMNThumbnailManager.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by 丁林圭 on 2024/10/21.
  6. //
  7. import Cocoa
  8. let kmnThumbnailFolder: String = {
  9. let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
  10. return (documentDirectory as NSString).appendingPathComponent("ThumbnailFolder")
  11. }()
  12. public class KMNThumbnail: NSObject {
  13. var thumbnailDocument:CPDFDocument = CPDFDocument()
  14. typealias KMNThumbnailCompletion = (_ image: NSImage?) -> Void
  15. var thumbnaiPage:CPDFPage?
  16. var pageSize:CGSize = CGSizeZero
  17. var pageIndex:Int = 0
  18. var isHoveBookMark:Bool {
  19. get {
  20. return thumbnailDocument.bookmark(forPageIndex: UInt(pageIndex)) != nil
  21. }
  22. }
  23. public var pageRotate:CGFloat = 0.0 {
  24. didSet {
  25. }
  26. }
  27. deinit {
  28. print("\(self.className) deinit")
  29. }
  30. public init(document: CPDFDocument,currentPageIndex:Int) {
  31. thumbnailDocument = document
  32. pageIndex = currentPageIndex
  33. let page = document.page(at: UInt(currentPageIndex))
  34. let size = page?.bounds(for: .cropBox).size
  35. pageSize = size ?? CGSize.zero
  36. thumbnaiPage = page
  37. pageRotate = 0
  38. super.init()
  39. }
  40. public override init() {
  41. super.init()
  42. }
  43. func generateThumImage(completion: KMNThumbnailCompletion?) {
  44. let filePathID = KMNThumbnailManager.filePathId(for: thumbnailDocument.documentURL.path)
  45. let docsFilePath = kmnThumbnailFolder + "/" + filePathID
  46. let fileManager = FileManager.default
  47. if !fileManager.fileExists(atPath: docsFilePath) {
  48. try? FileManager.default.createDirectory(atPath: docsFilePath, withIntermediateDirectories: true, attributes: nil)
  49. }
  50. let pageObjNum = thumbnaiPage?.getObjNum() ?? -1 //获取Page的唯一标识码
  51. var imageFilePath = ""
  52. if(pageObjNum == -1) {
  53. imageFilePath = ""
  54. } else {
  55. imageFilePath = docsFilePath + "/" + String(pageObjNum) + ".png"
  56. }
  57. var thumSize = pageSize
  58. if(imageFilePath.isEmpty == true) {
  59. let maxOrg = max(thumSize.width, thumSize.height)
  60. let minOrg = min(thumSize.width, thumSize.height)
  61. let maxWidth = 300.0
  62. let maxHeight = 500.0
  63. let scanW = maxWidth / minOrg
  64. let scanH = maxHeight / maxOrg
  65. let minScanl = min(scanW, scanH)
  66. if (thumbnaiPage?.rotation ?? 0) % 180 != 0 {
  67. thumSize.width = pageSize.height * minScanl
  68. thumSize.height = pageSize.width * minScanl
  69. } else {
  70. thumSize.width = pageSize.width * minScanl
  71. thumSize.height = pageSize.height * minScanl
  72. }
  73. thumbnaiPage?.thumbnail(of: thumSize, needReset: true,completion: { pageImage in
  74. if completion != nil {
  75. completion!(pageImage)
  76. }
  77. // 将 NSImage 转换为 PNG 数据
  78. guard let tiffData = pageImage?.tiffRepresentation,
  79. let bitmapImage = NSBitmapImageRep(data: tiffData),
  80. let pngData = bitmapImage.representation(using: .png, properties: [:]) else {
  81. return
  82. }
  83. do {
  84. try pngData.write(to: URL(fileURLWithPath: imageFilePath))
  85. } catch {
  86. }
  87. });
  88. } else {
  89. if fileManager.fileExists(atPath: imageFilePath) {
  90. let image = NSImage.init(contentsOfFile: imageFilePath) ?? NSImage()
  91. if completion != nil {
  92. completion!(image)
  93. }
  94. } else {
  95. let maxOrg = max(thumSize.width, thumSize.height)
  96. let minOrg = min(thumSize.width, thumSize.height)
  97. let maxWidth = 300.0
  98. let maxHeight = 500.0
  99. let scanW = maxWidth / minOrg
  100. let scanH = maxHeight / maxOrg
  101. let minScanl = min(scanW, scanH)
  102. if (thumbnaiPage?.rotation ?? 0) % 180 != 0 {
  103. thumSize.width = pageSize.height * minScanl
  104. thumSize.height = pageSize.width * minScanl
  105. } else {
  106. thumSize.width = pageSize.width * minScanl
  107. thumSize.height = pageSize.height * minScanl
  108. }
  109. thumbnaiPage?.thumbnail(of: thumSize, needReset: true,completion: { pageImage in
  110. if completion != nil {
  111. completion!(pageImage)
  112. }
  113. // 将 NSImage 转换为 PNG 数据
  114. guard let tiffData = pageImage?.tiffRepresentation,
  115. let bitmapImage = NSBitmapImageRep(data: tiffData),
  116. let pngData = bitmapImage.representation(using: .png, properties: [:]) else {
  117. return
  118. }
  119. do {
  120. try pngData.write(to: URL(fileURLWithPath: imageFilePath))
  121. } catch {
  122. }
  123. });
  124. }
  125. }
  126. }
  127. func removeCacheImage() {
  128. let filePathID = KMNThumbnailManager.filePathId(for: thumbnailDocument.documentURL.path)
  129. let docsFilePath = kmnThumbnailFolder + "/" + filePathID
  130. let fileManager = FileManager.default
  131. let pageObjNum = thumbnaiPage?.getObjNum() ?? -1
  132. var imageFilePath = ""
  133. if(pageObjNum == -1) {
  134. imageFilePath = ""
  135. } else {
  136. imageFilePath = docsFilePath + "/" + String(pageObjNum) + ".png"
  137. }
  138. if fileManager.fileExists(atPath: imageFilePath) {
  139. try? fileManager.removeItem(atPath: imageFilePath)
  140. }
  141. }
  142. }
  143. class KMNThumbnailManager: NSObject {
  144. static let manager = KMNThumbnailManager()
  145. var copyPages: [CPDFPage] = []
  146. var copyDocument: [CPDFDocument] = []
  147. class func filePathId(for filePath: String) -> String {
  148. return "\(filePath.hash)"
  149. }
  150. class func clearCacheFilePath(filePath:String) {
  151. let filePathID = KMNThumbnailManager.filePathId(for: filePath)
  152. let docsFilePath = kmnThumbnailFolder + "/" + filePathID
  153. let fileManager = FileManager.default
  154. if fileManager.fileExists(atPath: docsFilePath) {
  155. try? fileManager.removeItem(atPath: docsFilePath)
  156. }
  157. }
  158. class func clearCacheThumImage() {
  159. if FileManager.default.fileExists(atPath: kmnThumbnailFolder) {
  160. try?FileManager.default.removeItem(atPath: kmnThumbnailFolder)
  161. }
  162. }
  163. class func reloadThumImage(document:CPDFDocument,pageIndexs: IndexSet) {
  164. if pageIndexs.isEmpty == false {
  165. for i in pageIndexs {
  166. if i < document.pageCount {
  167. let thumbnail = KMNThumbnail.init(document: document, currentPageIndex: i)
  168. thumbnail.removeCacheImage()
  169. }
  170. }
  171. } else {
  172. for i in 0..<document.pageCount {
  173. let thumbnail = KMNThumbnail.init(document: document, currentPageIndex: Int(i))
  174. thumbnail.removeCacheImage()
  175. }
  176. }
  177. }
  178. }