KMScreenShotHandler.swift 6.1 KB

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