C#保存WPF/WinForm控件为图片 C#如何将界面元素截图并存为文件

来源:这里教程网 时间:2026-02-21 17:42:44 作者:

WPF控件导出为PNG:用
RenderTargetBitmap
+
JpegBitmapEncoder
/
PngBitmapEncoder

WPF不支持直接调用

DrawToBitmap
,必须走渲染管线。核心是把控件渲染到
RenderTargetBitmap
,再编码保存。注意:控件需已加载(
IsLoaded == true
),且不能处于隐藏状态(
Visibility == Visibility.Visible
)。

常见错误是控件未布局完成就截图,结果为空白或尺寸为0。建议在

Loaded
事件或
Dispatcher.InvokeAsync
中执行:

var bitmap = new RenderTargetBitmap((int)control.ActualWidth, (int)control.ActualHeight, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(control);
<p>var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));</p><p>using var fs = File.OpenWrite("output.png");
encoder.Save(fs);

关键点:

ActualWidth/ActualHeight
必须在布局完成后读取,否则为0
分辨率参数(96)影响清晰度,高DPI下可设为
VisualTreeHelper.GetDpi(control).PixelsPerInchX
若控件含
Effect
(如模糊、阴影),需确保
RenderOptions.SetBitmapScalingMode(control, BitmapScalingMode.HighQuality)
导出透明背景用
PngBitmapEncoder
;导出JPEG会丢弃Alpha通道

WinForm控件截图:用
Control.DrawToBitmap
但注意裁剪和DPI缩放

DrawToBitmap
是WinForm原生方案,但默认不处理DPI缩放——高DPI下截图会模糊或错位。必须先手动调整目标
Bitmap
尺寸,并启用
Graphics
的高质量渲染。

典型写法:

var bmp = new Bitmap(control.Width * control.DeviceDpi / 96, control.Height * control.DeviceDpi / 96);
using (var g = Graphics.FromImage(bmp))
{
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.SmoothingMode = SmoothingMode.HighQuality;
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    control.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
bmp.Save("output.jpg", ImageFormat.Jpeg);

易踩坑:

直接传
control.Size
Bitmap
构造函数 → 高DPI下图像被压缩拉伸
忽略
control.DeviceDpi
,硬编码96 → 多屏DPI不一致时出错
DrawToBitmap
无法捕获重叠在控件之上的浮层(如
ToolTip
、菜单)
某些自绘控件(如第三方图表)可能绕过GDI绘制,需调用其专属导出接口

跨窗口/全屏截图:用
Graphics.CopyFromScreen
Desktop duplication API

如果要截整个窗口(含非客户区)或桌面,

DrawToBitmap
RenderTargetBitmap
都失效。此时得用屏幕坐标抓取。

简单场景用

CopyFromScreen
(WinForm兼容):

var bounds = control.PointToScreen(new Point(0, 0));
var bmp = new Bitmap(control.Width, control.Height);
using (var g = Graphics.FromImage(bmp))
    g.CopyFromScreen(bounds, Point.Empty, control.Size);

但该方法有局限:

仅适用于可见区域,最小化窗口返回黑图 多显示器+不同DPI时,
PointToScreen
返回值需用
Monitor.FromPoint
校准
性能差,不适合高频截图(如录屏)

生产环境建议用Windows Desktop Duplication API(C++/COM),C#可通过

SharpDX
Windows.Graphics.Capture
(Win10 1803+)调用,支持捕获最小化窗口、硬件加速、Alpha通道。

保存路径与权限:避免
UnauthorizedAccessException
和中文路径乱码

截图保存失败最常见原因是路径不可写或含非法字符。WPF/WinForm默认运行在用户上下文,但若程序以管理员身份运行,而目标目录(如

C:\Program Files
)受UAC保护,就会抛
UnauthorizedAccessException

安全做法:

优先保存到
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
MyDocuments
路径含中文时,确保文件系统支持UTF-8(NTFS没问题,FAT32需注意) 使用
Path.Combine
拼接路径,避免手动加反斜杠导致
DirectoryNotFoundException
保存前检查父目录是否存在:
Directory.CreateDirectory(Path.GetDirectoryName(filePath))

另外,

FileStream
未显式指定
FileAccess.Write
或未用
using
释放,在部分杀毒软件下可能被拦截写入。

相关推荐