Skip to content

Commit 8b7042e

Browse files
authored
Merge pull request #69 from jasonjmcghee/rem-50-only-take-screenshot-if-display-changed
[rem-50]: Only take a screenshot + ocr if the frame changed
2 parents 579ca19 + 8f073cc commit 8b7042e

File tree

1 file changed

+42
-20
lines changed

1 file changed

+42
-20
lines changed

rem/remApp.swift

+42-20
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
8888
private var wasRecordingBeforeSleep: Bool = false
8989
private var wasRecordingBeforeTimelineView: Bool = false
9090
private var wasRecordingBeforeSearchView: Bool = false
91+
92+
private var lastImageData: Data? = nil
93+
private var lastActiveApplication: String? = nil
9194

9295
func applicationDidFinishLaunching(_ notification: Notification) {
9396
let _ = DatabaseManager.shared
@@ -321,6 +324,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {
321324
let text = TextMerger.shared.mergeTexts(texts: texts)
322325
ClipboardManager.shared.replaceClipboardContents(with: text)
323326
}
327+
328+
private func displayImageChangedFromLast(imageData: Data) -> Bool {
329+
if let prevImage = lastImageData {
330+
return prevImage.withUnsafeBytes { ptr1 in
331+
imageData.withUnsafeBytes { ptr2 in
332+
memcmp(ptr1.baseAddress, ptr2.baseAddress, imageData.count) != 0
333+
}
334+
}
335+
}
336+
return false
337+
}
324338

325339
private func scheduleScreenshot(shareableContent: SCShareableContent) {
326340
Task {
@@ -335,27 +349,38 @@ class AppDelegate: NSObject, NSApplicationDelegate {
335349
// Do we want to record the timeline being searched?
336350
guard let image = CGDisplayCreateImage(display.displayID, rect: display.frame) else { return }
337351

338-
let frameId = DatabaseManager.shared.insertFrame(activeApplicationName: activeApplicationName)
352+
let bitmapRep = NSBitmapImageRep(cgImage: image)
353+
guard let imageData = bitmapRep.representation(using: .png, properties: [:]) else { return }
339354

340-
if settingsManager.settings.onlyOCRFrontmostWindow {
341-
// User wants to perform OCR on only active window.
355+
// Might as well only check if the applications are the same, otherwise obviously different
356+
if activeApplicationName != lastActiveApplication || displayImageChangedFromLast(imageData: imageData) {
357+
lastImageData = imageData;
358+
lastActiveApplication = activeApplicationName;
342359

343-
// We need to determine the scale factor for cropping. CGImage is
344-
// measured in pixels, display sizes are measured in points.
345-
let scale = max(CGFloat(image.width) / CGFloat(display.width), CGFloat(image.height) / CGFloat(display.height))
360+
let frameId = DatabaseManager.shared.insertFrame(activeApplicationName: activeApplicationName)
346361

347-
if
348-
let window = shareableContent.windows.first(where: { $0.isOnScreen && $0.owningApplication?.processID == NSWorkspace.shared.frontmostApplication?.processIdentifier }),
349-
let cropped = ImageHelper.cropImage(image: image, frame: window.frame, scale: scale)
350-
{
351-
self.performOCR(frameId: frameId, on: cropped)
362+
if settingsManager.settings.onlyOCRFrontmostWindow {
363+
// User wants to perform OCR on only active window.
364+
365+
// We need to determine the scale factor for cropping. CGImage is
366+
// measured in pixels, display sizes are measured in points.
367+
let scale = max(CGFloat(image.width) / CGFloat(display.width), CGFloat(image.height) / CGFloat(display.height))
368+
369+
if
370+
let window = shareableContent.windows.first(where: { $0.isOnScreen && $0.owningApplication?.processID == NSWorkspace.shared.frontmostApplication?.processIdentifier }),
371+
let cropped = ImageHelper.cropImage(image: image, frame: window.frame, scale: scale)
372+
{
373+
self.performOCR(frameId: frameId, on: cropped)
374+
}
375+
} else {
376+
// default: User wants to perform OCR on full display.
377+
self.performOCR(frameId: frameId, on: image)
352378
}
379+
380+
await processScreenshot(frameId: frameId, imageData: imageData, frame: display.frame)
353381
} else {
354-
// default: User wants to perform OCR on full display.
355-
self.performOCR(frameId: frameId, on: image)
382+
logger.info("Screen didn't change! Not processing frame.")
356383
}
357-
358-
await processScreenshot(frameId: frameId, image: image, frame: display.frame)
359384
} catch {
360385
logger.error("Error taking screenshot: \(error)")
361386
}
@@ -406,14 +431,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
406431
// }
407432
// }
408433

409-
private func processScreenshot(frameId: Int64, image: CGImage, frame: CGRect) async {
410-
let bitmapRep = NSBitmapImageRep(cgImage: image)
411-
guard let data = bitmapRep.representation(using: .png, properties: [:]) else { return }
412-
434+
private func processScreenshot(frameId: Int64, imageData: Data, frame: CGRect) async {
413435
imageBufferQueue.async(flags: .barrier) { [weak self] in
414436
guard let strongSelf = self else { return }
415437

416-
strongSelf.imageDataBuffer.append(data)
438+
strongSelf.imageDataBuffer.append(imageData)
417439

418440
// Quickly move the images to a temporary buffer if the threshold is reached
419441
var tempBuffer: [Data] = []

0 commit comments

Comments
 (0)