From a74a86d001c402be475b6bf324bd0e6efd180a3c Mon Sep 17 00:00:00 2001 From: TZGyn Date: Sun, 23 Aug 2026 13:27:41 +0800 Subject: [PATCH] Fix vertical offset in ScreenCaptureKit crops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The captured CGImage has a top-left origin, while the crop rect was computed in SCDisplay space (bottom-left). Flip Y within the display's bounds when converting to pixel coordinates so the crop lands exactly where the user selected. 💘 Generated with Crush Assisted-by: Crush:deepseek-v4-flash-0731 --- Sources/Kapture/CaptureController.swift | 16 ++++++++-------- build-app.sh | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Sources/Kapture/CaptureController.swift b/Sources/Kapture/CaptureController.swift index 9df7235..30b0f72 100644 --- a/Sources/Kapture/CaptureController.swift +++ b/Sources/Kapture/CaptureController.swift @@ -118,18 +118,18 @@ final class ScreenCapture { @available(macOS 14.0, *) private func crop(_ image: CGImage, to cgRect: CGRect, display: SCDisplay) -> CGImage? { - // cgRect is already in SCDisplay space (Y flipped relative to AppKit). - // Derive the pixel scale from the image we actually got, relative to - // the display's point frame. + // cgRect is in SCDisplay space (bottom-left origin, Y flipped vs AppKit). + // The captured image has a TOP-LEFT origin. So within the display, + // we must flip Y: pixelY = displayHeight - (cgY - displayMinY) - cgHeight. let scaleX = CGFloat(image.width) / display.frame.width let scaleY = CGFloat(image.height) / display.frame.height guard scaleX > 0, scaleY > 0 else { return nil } - // pxRect is in image pixel space with a TOP-LEFT origin (SCDisplay space). - // CGImage.cropping(to:) expects the same top-left rect, so no Y flip - // is needed here — this preserves the previous CGContext behavior. + let localMinX = cgRect.minX - display.frame.minX + let localMaxY = cgRect.maxY - display.frame.minY + let flippedY = display.frame.height - localMaxY let pxRect = CGRect( - x: (cgRect.minX - display.frame.minX) * scaleX, - y: (cgRect.minY - display.frame.minY) * scaleY, + x: localMinX * scaleX, + y: flippedY * scaleY, width: cgRect.width * scaleX, height: cgRect.height * scaleY ) diff --git a/build-app.sh b/build-app.sh index df558df..c6d8db9 100755 --- a/build-app.sh +++ b/build-app.sh @@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST' CFBundleIconFile Icon CFBundleShortVersionString - 1.3.1 + 1.3.2 CFBundleVersion - 31 + 32 LSUIElement NSHighResolutionCapable