
Captura 是一款功能强大、完全免费的屏幕录制和截图工具。它不仅可以帮助您轻松创建高质量的视频教程、游戏录像和会议记录,还提供了丰富的定制选项,让您的录制过程更加专业和高效。从简单的截图到复杂的多音轨视频录制,Captura 都能轻松应对。
Captura 提供了一系列强大而实用的功能,满足您在不同场景下的需求:
Captura 提供多种安装方式,您可以根据自己的偏好选择。
Captura-Setup.exe (安装版) 或 Captura-Portable.zip (便携版)。便携版解压后即可使用,无需安装。Captura 的用户界面非常直观,主要功能都集中在主窗口。以下是一些基础使用示例。
Ctrl+F10)开始录制。Ctrl+F11)暂停录制。Ctrl+F10)停止录制。视频将自动保存到您的输出文件夹。Captura 的项目结构清晰,模块化程度高,以下是几个核心模块的代码示例,展示了其部分实现。
App.xaml.cs)using FirstFloor.ModernUI.Presentation;
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
using Captura.Loc;
using Captura.Models;
using Captura.MouseKeyHook;
using Captura.ViewModels;
using Captura.Views;
using CommandLine;
namespace Captura
{
public partial class App
{
public App()
{
// 单例模式检查,防止多开
SingleInstanceManager.SingleInstanceCheck();
// 显示启动画面
ShowSplashScreen();
}
public static CmdOptions CmdOptions { get; private set; }
// 全局UI线程异常处理
void App_OnDispatcherUnhandledException(object Sender, DispatcherUnhandledExceptionEventArgs Args)
{
var dir = Path.Combine(ServiceProvider.SettingsDir, "Crashes");
Directory.CreateDirectory(dir);
File.WriteAllText(Path.Combine(dir, $"{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt"), Args.Exception.ToString());
Args.Handled = true;
new ErrorWindow(Args.Exception, Args.Exception.Message).ShowDialog();
}
void Application_Startup(object Sender, StartupEventArgs Args)
{
AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainOnUnhandledException;
// 加载核心模块(依赖注入)
ServiceProvider.LoadModule(new CoreModule());
ServiceProvider.LoadModule(new ViewCoreModule());
// 解析命令行参数
Parser.Default.ParseArguments<CmdOptions>(Args.Args)
.WithParsed(M => CmdOptions = M);
if (CmdOptions.Settings != null)
{
ServiceProvider.SettingsDir = CmdOptions.Settings;
}
var settings = ServiceProvider.Get<Settings>();
// 初始化主题、语言、快捷键映射
InitTheme(settings);
BindLanguageSetting(settings);
BindKeymapSetting(settings);
}
// ... 其他初始化方法
}
}VideoSourcePickerWindow.xaml.cs)这个窗口允许用户通过直观的界面选择要录制的窗口或屏幕。
using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using Captura.Video;
using Color = System.Windows.Media.Color;
using Cursors = System.Windows.Input.Cursors;
using HorizontalAlignment = System.Windows.HorizontalAlignment;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
namespace Captura
{
public partial class VideoSourcePickerWindow
{
enum VideoPickerMode { Window, Screen }
readonly VideoPickerMode _mode;
Predicate<IWindow> Predicate { get; set; }
VideoSourcePickerWindow(VideoPickerMode Mode)
{
_mode = Mode;
InitializeComponent();
// 窗口铺满整个虚拟屏幕
Left = SystemParameters.VirtualScreenLeft;
Top = SystemParameters.VirtualScreenTop;
Width = SystemParameters.VirtualScreenWidth;
Height = SystemParameters.VirtualScreenHeight;
UpdateBackground(); // 截取当前屏幕作为背景
var platformServices = ServiceProvider.Get<IPlatformServices>();
_screens = platformServices.EnumerateScreens().ToArray();
_windows = platformServices.EnumerateWindows().ToArray();
ShowCancelText();
}
readonly IScreen[] _screens;
readonly IWindow[] _windows;
public IScreen SelectedScreen { get; private set; }
public IWindow SelectedWindow { get; private set; }
// 截取屏幕作为背景,实现“透视”效果
void UpdateBackground()
{
using var bmp = ScreenShot.Capture();
var stream = new MemoryStream();
bmp.Save(stream, ImageFormats.Png);
stream.Seek(0, SeekOrigin.Begin);
var decoder = new PngBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
Background = new ImageBrush(decoder.Frames[0]);
}
// ... 其他交互逻辑
}
}NotificationStack.xaml.cs)Captura 使用一个优雅的通知堆栈来管理截图预览和操作反馈。
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
namespace Captura
{
public partial class NotificationStack
{
static readonly TimeSpan TimeoutToHide = TimeSpan.FromSeconds(5);
DateTime _lastMouseMoveTime;
readonly DispatcherTimer _timer;
public NotificationStack()
{
InitializeComponent();
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
_timer.Tick += TimerOnTick;
_timer.Start();
}
void TimerOnTick(object Sender, EventArgs Args)
{
var now = DateTime.Now;
var elapsed = now - _lastMouseMoveTime;
// 检查是否有未完成的通知(如正在上传)
var unfinished = ItemsControl.Items
.OfType<NotificationBalloon>()
.Any(M => !M.Notification.Finished);
if (unfinished)
{
_lastMouseMoveTime = now;
}
if (elapsed < TimeoutToHide)
return;
if (!unfinished)
{
OnClose(); // 自动隐藏
}
}
public void Hide()
{
BeginAnimation(OpacityProperty, new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(100))));
if (_timer.IsEnabled)
_timer.Stop();
}
public void Show()
{
_lastMouseMoveTime = DateTime.Now;
BeginAnimation(OpacityProperty, new DoubleAnimation(1, new Duration(TimeSpan.FromMilliseconds(300))));
if (!_timer.IsEnabled)
_timer.Start();
}
// 移除指定元素,并伴有滑出动画
void Remove(FrameworkElement Element)
{
var transform = new TranslateTransform();
Element.RenderTransform = transform;
var translateAnim = new DoubleAnimation(500, new Duration(TimeSpan.FromMilliseconds(200)));
var opactityAnim = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(200)));
var heightAnim = new DoubleAnimation(Element.ActualHeight, 0, new Duration(TimeSpan.FromMilliseconds(200)));
heightAnim.Completed += (S, E) => ItemsControl.Items.Remove(Element);
opactityAnim.Completed += (S, E) => Element.BeginAnimation(HeightProperty, heightAnim);
transform.BeginAnimation(TranslateTransform.XProperty, translateAnim);
Element.BeginAnimation(OpacityProperty, opactityAnim);
}
// ... 添加通知、鼠标移动处理等方法
}
}
```FINISHED9EN9f9Pid8T89KjZma8Lo9oN+oe+voeUx2TBEXvxyQA=
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。