Free tools Windows power users keep installed
One-click scans. No signup required.
For a new macOS app, use Apple’s ScreenCaptureKit. Call SCScreenshotManager.captureImage(contentFilter:configuration:) when you need one still image; use SCStream when you need a continuing sequence of frames. ScreenCaptureKit can target a display, running application, or window through SCShareableContent and SCContentFilter. Request Screen Recording permission first and add NSScreenCaptureUsageDescription to the app’s Info property list.
Choose the capture API for the job
| Need | Use | What you receive |
|---|---|---|
| Web-page screenshots without managing a macOS capture app | ScreenshotNeo | A PNG, JPEG, WebP, or PDF from one HTTP request. It removes common consent banners, popups, and chat widgets before capture; only clean shots are billed. |
| One still image from macOS content | SCScreenshotManager.captureImage |
A single CGImage produced from an SCContentFilter and SCStreamConfiguration. |
| Video-like or repeated captures | SCStream |
Video (and optionally audio) sample buffers delivered to a stream-output delegate. |
| Let the person choose what to share | SCContentSharingPicker |
Apple’s system selection interface for displays, apps, windows, and active streams. |
| Existing legacy code | CGWindowListCreateImage |
A deprecated Core Graphics path. Do not make it the default for new work. |
Apple’s ScreenCaptureKit overview describes the content model and picker. The dedicated captureImage documentation defines the one-frame operation, while Apple’s macOS capture sample demonstrates selecting content and configuring a stream.
Prerequisites and privacy permission
Add the usage description
In Xcode, select the app target, open Info, and add Privacy - Screen Recording Usage Description (the key is NSScreenCaptureUsageDescription). Use a specific explanation such as “This app captures the selected window to create a support image.” Apple explicitly tells developers to request permission from the person before capturing content.
Request access in macOS
- Start the app and trigger a capture only after explaining why access is needed.
- When macOS displays the Screen Recording prompt, choose Open System Settings and enable the app under Privacy & Security > Screen Recording.
- Return to the app and retry. Apple’s sample requires a restart after permission is granted; treat that as sample behavior rather than a universal rule for every app and OS version.
If permission was denied, the user can enable it later in System Settings. Your app should detect a failed or empty content result and provide that path instead of silently saving a blank image.
#1 Best Overall
Capture one display, app, or window in Swift
The workflow
- Ask ScreenCaptureKit for
SCShareableContent. - Choose a display, application, or window from the returned collections.
- Create an
SCContentFilterdescribing included or excluded content. - Set width, height, pixel format, and other options on
SCStreamConfiguration. - Call
SCScreenshotManager.captureImageand encode the returnedCGImage.
Complete async example (macOS 15 SDK, Xcode 16)
Apple’s sample project lists macOS 15 or later and Xcode 16 or later as its requirements. Those are sample requirements, not a claim that every ScreenCaptureKit symbol has that minimum deployment target; check SDK availability annotations for your deployment range.
import ScreenCaptureKit
import CoreGraphics
import ImageIO
import UniformTypeIdentifiers
@available(macOS 15.0, *)
func captureFirstDisplay(to url: URL) async throws {
// The arrays contain displays, applications, and windows the user allows.
let content = try await SCShareableContent.excludingDesktopWindows(
false,
onScreenWindowsOnly: true
)
guard let display = content.displays.first else {
throw NSError(domain: "Capture", code: 1,
userInfo: [NSLocalizedDescriptionKey: "No display is available"])
}
// Capture this display. For a window, use
// SCContentFilter(desktopIndependentWindow: selectedWindow).
let filter = SCContentFilter(
display: display,
excludingApplications: [],
exceptingWindows: []
)
let configuration = SCStreamConfiguration()
configuration.width = display.width
configuration.height = display.height
configuration.pixelFormat = kCVPixelFormatType_32BGRA
configuration.showsCursor = true
configuration.capturesAudio = false
let image = try await SCScreenshotManager.captureImage(
contentFilter: filter,
configuration: configuration
)
guard let destination = CGImageDestinationCreateWithURL(
url as CFURL,
UTType.png.identifier as CFString,
1,
nil
) else {
throw NSError(domain: "Capture", code: 2,
userInfo: [NSLocalizedDescriptionKey: "Cannot create PNG destination"])
}
CGImageDestinationAddImage(destination, image, nil)
guard CGImageDestinationFinalize(destination) else {
throw NSError(domain: "Capture", code: 3,
userInfo: [NSLocalizedDescriptionKey: "PNG encoding failed"])
}
}
Call the function from an asynchronous context and supply a writable URL, for example in your app’s Documents directory. Handle the thrown error and show a permission or “no shareable content” explanation rather than presenting a generic failure.
Capture a particular window
Find the desired SCWindow in content.windows (match its title, owning application, or process identifier), then construct SCContentFilter(desktopIndependentWindow: window). A window can be minimized, closed, or become invalid between discovery and capture, so re-fetch shareable content when a capture fails and let the person select again.
Capture an application
Match an SCRunningApplication in content.applications and build the application filter supported by your SDK. An app may own several windows; decide whether your product needs all of them or a single window and communicate that scope in the UI.
Rank #2
- Mix an audio, music and voice tracks
- Record single or multiple tracks simultaneously
- Intuitive tools to split, trim, join, and many other editing features
- Loaded with audio effects including EQ, compression, reverb, and more.
- Load an audio file and export to all popular audio formats from studio quality wav to high compression formats
Exclude your own app from a display capture
When the app’s control panel would otherwise appear in the result, pass it in the filter’s excluded-application list. Apple’s sample demonstrates a display filter that excludes the capturing app. Keep the exclusion intentional: excluding the wrong process can remove content the person expected to see.
When the person should choose the source
Use SCContentSharingPicker when a person needs to select a display, application, or window at runtime. Apple recommends the system picker instead of a home-grown source-selection interface. It also manages active streams, reducing the amount of permission-sensitive selection code your app must maintain. Programmatic filters remain appropriate for a fixed workflow, such as “capture the currently selected support window.”
Capture a continuing stream with SCStream
A screenshot and a stream have different lifecycles. Configure an SCStream with the same kind of content filter, add an output handler, and start capture. The handler receives sample buffers that you can display, encode, or process. Audio is optional; enable it only when the feature needs it.
import ScreenCaptureKit
import CoreMedia
final class FrameReceiver: NSObject, SCStreamOutput {
func stream(_ stream: SCStream,
didOutputSampleBuffer sampleBuffer: CMSampleBuffer,
of type: SCStreamOutputType) {
guard type == .screen,
CMSampleBufferIsValid(sampleBuffer) else { return }
// Send the video sample buffer to your renderer or encoder.
}
}
@available(macOS 15.0, *)
func startDisplayStream() async throws -> SCStream {
let content = try await SCShareableContent.excludingDesktopWindows(
false, onScreenWindowsOnly: true
)
guard let display = content.displays.first else { throw CaptureError.noDisplay }
let filter = SCContentFilter(display: display,
excludingApplications: [],
exceptingWindows: [])
let config = SCStreamConfiguration()
config.width = display.width
config.height = display.height
config.minimumFrameInterval = CMTime(value: 1, timescale: 30)
config.capturesAudio = false
let receiver = FrameReceiver()
let stream = SCStream(filter: filter, configuration: config, delegate: nil)
try stream.addStreamOutput(receiver, type: .screen, sampleHandlerQueue: .main)
try await stream.startCapture()
return stream
}
enum CaptureError: Error { case noDisplay }
Retain the output delegate for as long as the stream runs. Stop the stream when the user finishes, and remove outputs during teardown. For background capture, configure the appropriate background execution modes; do not assume a regular foreground app can capture indefinitely after it is suspended.
Rank #3
- Easily record quick videos of your screen and camera that offer the same connection as a meeting without the calendar wrangling
- Draw on your screen as you record video with customizable arrows, squares, and step numbers to emphasize important information
- Provide clear feedback and explain complex concepts with easy-to-use professional mark-up tools and templates
- Instantly create a shareable link where your viewers can leave comments and annotations or upload directly to the apps you use every day
- Version Note: This listing is for Snagit 2024. Please note that official technical support and software updates for this version are scheduled to conclude on December 31, 2026.
Configuration choices that affect results
- Dimensions: Set
widthandheightdeliberately. Larger output preserves detail but increases memory, encoding time, and stream bandwidth. - Frame rate: For streams,
minimumFrameIntervalcontrols capture cadence. A still image does not need a video frame rate. - Cursor: Set
showsCursoraccording to whether the pointer is part of the evidence. - Audio:
capturesAudiois an additional stream capability, not a requirement for screenshots. - Filter scope: A display filter may include multiple windows; a window filter limits the result to one desktop-independent window.
- Processing: Encode a still
CGImageto PNG, JPEG, or another format with Image I/O. For streams, process sample buffers off the main thread when possible.
Legacy CGWindowListCreateImage: why migration matters
CGWindowListCreateImage is deprecated. Apple’s macOS Sequoia 15 release notes warn that applications using deprecated content-capture APIs such as CGDisplayStream and CGWindowListCreateImage can trigger alerts saying they might collect detailed information about the user. The same release notes direct developers toward ScreenCaptureKit and SCContentSharingPicker. Keep the old call only while planning a migration; do not present it as the modern macOS screenshot API.
Or skip the browser setup
If the real task is capturing public web pages rather than the Mac desktop, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers.
One request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for parameters and response details. The same call in Python is:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
And in Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its 63 options include full-page lazy-image loading, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper settings and page ranges, custom CSS or JavaScript, pre-capture clicks, selector waits, network-idle waits, ad and tracker blocking, custom headers/cookies/user agents, Authorization, timezone and geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of 100 URLs per call, usage reporting, and an OpenAPI specification. Common parameter names from other screenshot APIs are accepted to ease migration.
Recommended Free Tools
| Plan | Included shots | Price |
|---|---|---|
| Free | 1,000 per month | $0; no card |
| Starter | 3,000 | $5 |
| Growth | 15,000 | $15 |
| Pro | 60,000 | $39 |
| Scale | 250,000 | $99 |
| Business | 1,000,000 | $249 |
Every feature is available on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to get 1,000 screenshots a month without a card.
Rank #4
- Create a mix using audio, music and voice tracks and recordings.
- Customize your tracks with amazing effects and helpful editing tools.
- Use tools like the Beat Maker and Midi Creator.
- Work efficiently by using Bookmarks and tools like Effect Chain, which allow you to apply multiple effects at a time
- Use one of the many other NCH multimedia applications that are integrated with MixPad.
Troubleshooting checklist
The content list is empty
Screen Recording permission is missing, the user has not approved the app, or the requested content no longer exists. Confirm NSScreenCaptureUsageDescription, check Privacy & Security > Screen Recording, and call SCShareableContent again after approval.
The image is black, blank, or incomplete
Verify that the filter points to a live display or window and that dimensions are non-zero. A window can disappear between enumeration and capture; refresh content and retry. Protected or secure surfaces may not be capturable, so provide a clear “content unavailable” state rather than repeatedly retrying.
The app captures its own controls
Use the display filter’s excluded-application list to omit your process, as shown in Apple’s sample. For a precise result, capture the selected window instead of the entire display.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Capture works once, then fails
Keep the selected SCWindow or SCDisplay only for the duration you need it. Re-enumerate shareable content after display changes, app termination, permission changes, or picker updates.
Best Value
- The 2ID card software streamlines various card production tasks such as ID card design, printing, and encoding.
- It's a versatile product suitable for various organizations, including universities, government agencies, large corporations, and those in need of registration, identification, and access control.
- Start creating custom ID cards seamlessly with 2ID card software.
The stream consumes too many resources
Lower configured dimensions or frame rate, avoid unnecessary audio, and move encoding and image analysis away from the main queue. Stop the stream when its consumer is no longer visible.
Users see a privacy alert after an OS update
Replace deprecated Core Graphics capture calls with ScreenCaptureKit and, where user selection is needed, SCContentSharingPicker. Apple specifically associates such alerts with deprecated capture APIs in the macOS Sequoia 15 release notes.
Performance, reliability, and cost considerations
Apple’s documentation cited here does not provide a topic-specific performance benchmark. Measure on the macOS versions, display scales, and resolutions your app supports. For stills, avoid requesting a larger image than the destination requires. For streams, bound your queue, drop frames when downstream processing falls behind, and release buffers promptly. Treat permission state, display topology, and window lifetime as changing inputs rather than one-time setup.
ScreenCaptureKit itself has no per-shot service charge: it runs inside your app and uses the Mac’s resources. A hosted web-page workflow has different economics. ScreenshotNeo’s only-bill-clean-shots policy, cache-hit exclusion, and visible verdict headers make it possible to reconcile usage; select a plan from the published allowances rather than assuming every HTTP request is billable.
Frequently Asked Questions
Can a ScreenCaptureKit screenshot be saved as JPEG instead of PNG?
Yes. The capture method returns a CGImage; use Image I/O with a JPEG destination and supply an appropriate compression dictionary when encoding.
Is the ScreenCaptureKit sample’s macOS 15 requirement the minimum for every app?
No. It is the requirement stated for Apple’s sample project. Check availability annotations in the SDK and the macOS versions your app supports before choosing a deployment target.
Should an app build its own screen-source picker?
Usually not when the person must choose content. Apple recommends SCContentSharingPicker for that interaction; use programmatic filters for deliberate, fixed selections.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

