KMScreenShotHandler.swift 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //
  2. // KMScreenShotHandler.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by liujiajie on 2024/1/24.
  6. //
  7. import Foundation
  8. let KMCancelCurrentCapturingActionNotification = "KMCancelCurrentCapturingActionNotification"
  9. class KMScreenShotHandler: NSObject{
  10. var isCapturing = false
  11. static let defaultManager = KMScreenShotHandler()
  12. static var screenShotWindow: KMScreenShotMaskWindowController!
  13. class func fullScreenShot() -> NSImage {
  14. var screenShot = CGWindowListCreateImage(.infinite, .optionOnScreenOnly, kCGNullWindowID, [])
  15. let img2 = NSImage(cgImage: screenShot!, size: NSZeroSize)
  16. screenShot = nil
  17. return img2
  18. }
  19. class func appointWindowScreenShot(withWindowID windowID: CGWindowID) -> NSImage? {
  20. let windowImage = CGWindowListCreateImage(.null, .optionIncludingWindow, windowID, [])
  21. let newImage = imageFromCGImageRef(windowImage)
  22. return newImage
  23. }
  24. class func imageFromCGImageRef(_ image: CGImage?) -> NSImage? {
  25. var imageRect = NSRect(x: 0.0, y: 0.0, width: 0.0, height: 0.0)
  26. var imageContext: CGContext?
  27. var newImage: NSImage?
  28. // Get the image dimensions.
  29. imageRect.size.height = CGFloat(image?.height ?? 0)
  30. imageRect.size.width = CGFloat(image?.width ?? 0)
  31. // Create a new image to receive the Quartz image data.
  32. if imageRect.size == CGSize.zero {
  33. return newImage
  34. }
  35. newImage = NSImage(size: imageRect.size)
  36. newImage?.lockFocus()
  37. // Get the Quartz context and draw.
  38. imageContext = NSGraphicsContext.current?.cgContext
  39. imageContext?.draw(image!, in: NSRectToCGRect(imageRect))
  40. newImage?.unlockFocus()
  41. return newImage
  42. }
  43. class func screenPosition(for event: NSEvent) -> CGPoint {
  44. var point = event.locationInWindow
  45. point.x += event.window?.frame.origin.x ?? 0
  46. point.y += event.window?.frame.origin.y ?? 0
  47. return point
  48. }
  49. class func calculateString(_ aString: String, font aFont: NSFont) -> CGSize {
  50. let attributeString = NSMutableAttributedString(string: aString)
  51. let style = NSMutableParagraphStyle()
  52. style.lineSpacing = 10
  53. attributeString.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: aString.count))
  54. attributeString.addAttribute(.font, value: aFont, range: NSRange(location: 0, length: aString.count))
  55. let options: NSString.DrawingOptions = [.usesLineFragmentOrigin, .usesFontLeading]
  56. let rect = attributeString.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: options, context: nil)
  57. return CGSize(width: rect.size.width + 10, height: rect.size.height)
  58. }
  59. class func imageToPDFViaSavePanel(_ image: NSImage) {
  60. DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
  61. let savePanel = NSSavePanel()
  62. let originalPDFName = "untitled"
  63. savePanel.nameFieldStringValue = originalPDFName + "_ScreenShot"
  64. savePanel.allowedFileTypes = ["pdf"]
  65. savePanel.begin { (result) in
  66. if result == .OK {
  67. let newDocument = CPDFDocument()
  68. _ = newDocument?.km_insert(imageData: image.jpgData() ?? Data(), pageSize: image.size, at: 0)
  69. let isSuccess = newDocument?.write(to: savePanel.url!)
  70. if isSuccess ?? false {
  71. NSDocumentController.shared.openDocument(withContentsOf: savePanel.url!, display: true) { (document, documentWasAlreadyOpen, error) in
  72. // Handle completion
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. class func imageToPDF(_ image: NSImage) -> CPDFDocument? {
  80. let newDocument = CPDFDocument()
  81. _ = newDocument?.km_insert(imageData: image.jpgData() ?? Data(), pageSize: image.size, at: 0)
  82. let savePath = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).last!.appending("/\(Bundle.main.bundleIdentifier!)/ScreenShot.pdf")
  83. let isSuccess = newDocument?.write(to: URL(fileURLWithPath: savePath))
  84. if isSuccess ?? false {
  85. return newDocument
  86. }
  87. return nil
  88. }
  89. class func beginScreenShot_SelectWindowCompleteHandler(_ handler: @escaping captureScreenCallBack) {
  90. if KMScreenShotHandler.defaultManager.isCapturing == true {
  91. NotificationCenter.default.post(name: Notification.Name(KMCancelCurrentCapturingActionNotification), object: nil)
  92. }
  93. screenShotWindow = KMScreenShotMaskWindowController { (ima) in
  94. if let image = ima {
  95. handler(image)
  96. }
  97. }
  98. screenShotWindow.beginImageCapture(true)
  99. }
  100. class func beginScreenShot_FullSreenWithDelayTime(_ delayTime: NSInteger, completeHandler handler: @escaping captureScreenCallBack) {
  101. if KMScreenShotHandler.defaultManager.isCapturing {
  102. NotificationCenter.default.post(name: Notification.Name(KMCancelCurrentCapturingActionNotification), object: nil)
  103. }
  104. KMScreenShotHandler.defaultManager.isCapturing = true
  105. screenShotWindow = KMScreenShotMaskWindowController(fullScreenShot: delayTime, completeHandler: { (ima) in
  106. KMScreenShotHandler.defaultManager.isCapturing = false
  107. if let image = ima {
  108. handler(image)
  109. }
  110. })
  111. }
  112. class func beginScreenshot_SelectRectWithCompleteHandler(_ handler: @escaping captureScreenCallBack) {
  113. if KMScreenShotHandler.defaultManager.isCapturing {
  114. NotificationCenter.default.post(name: Notification.Name(KMCancelCurrentCapturingActionNotification), object: nil)
  115. }
  116. screenShotWindow = KMScreenShotMaskWindowController( handler: { (ima) in
  117. if let image = ima {
  118. handler(image)
  119. }
  120. })
  121. screenShotWindow.beginImageCapture(false)
  122. }
  123. // func setIsCapturing(iscapturing: Bool) {
  124. // self.isCapturing = iscapturing
  125. // }
  126. }