为何设置.captureResolution为.best及高分辨率后,ScreenCaptureKit截图仍模糊?
解决ScreenCaptureKit静态截图模糊问题
核心问题分析
你的代码里同时设置了sourceRect(800x800的截取区域)和远大于该区域的输出尺寸(7680x4320),这种跨比例的强制拉伸会导致截图模糊。另外pixelFormat的选择、NSImage的初始化方式也可能影响最终画质。
修复方案
1. 匹配截取区域与输出尺寸的比例
如果要截取全屏,直接移除sourceRect设置;如果要截取指定区域,确保输出尺寸和sourceRect的宽高比完全一致,避免非等比例拉伸。比如截取800x800的区域,输出尺寸可设为1600x1600(2倍等比例放大),而非7680x4320。
2. 调整SCStreamConfiguration参数
- 若依赖
captureResolution = .best获取最佳画质,可移除width和height的强制设置,让系统自动适配显示器原生分辨率;若需指定输出尺寸,必须保证与sourceRect比例一致。 - 将
pixelFormat改为kCVPixelFormatType_32RGBA,该格式更适配静态截图,减少色彩转换带来的画质损失。 - 保留
preservesAspectRatio = true和scalesToFit = false的组合,但需确保比例匹配。
3. 正确初始化NSImage
使用capturedImage的实际尺寸初始化NSImage,避免系统自动缩放导致模糊:
let nsImageSize = NSSize(width: capturedImage.width, height: capturedImage.height) let nsImage = NSImage(cgImage: capturedImage, size: nsImageSize)
修复后的完整代码
@objc func takeScreenshot() { Task { do { let content = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: false) guard let mainDisplayID = NSScreen.main?.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID, let display = content.displays.first(where: { $0.displayID == mainDisplayID }) else { return } let configuration = SCStreamConfiguration() configuration.captureResolution = .best // 如需截取指定区域,确保输出尺寸与sourceRect比例一致 // configuration.sourceRect = CGRect(x: 400, y: 400, width: 800, height: 800) // configuration.width = 800 * 2 // configuration.height = 800 * 2 // 如需全屏2倍分辨率截图,直接基于显示器尺寸设置 let nativeSize = NSScreen.main?.frame.size ?? .zero configuration.width = Int(nativeSize.width * 2) configuration.height = Int(nativeSize.height * 2) configuration.pixelFormat = kCVPixelFormatType_32RGBA configuration.preservesAspectRatio = true configuration.capturesAudio = false configuration.scalesToFit = false let filter = SCContentFilter(display: display, excludingWindows: []) let capturedImage = try await SCScreenshotManager.captureImage(contentFilter: filter, configuration: configuration) let nsImageSize = NSSize(width: capturedImage.width, height: capturedImage.height) let nsImage = NSImage(cgImage: capturedImage, size: nsImageSize) self.imageView.image = nsImage } catch { print("Error capturing screen: \(error)") } } }
额外注意事项
- 确保App已获取屏幕录制权限(系统偏好设置>隐私与安全性>屏幕录制),权限不足可能导致画质降级。
- 若截取指定区域,优先使用等比例缩放,避免强制拉伸。
内容的提问来源于stack exchange,提问作者KanKonga
相关产品推荐
相关产品推荐

