如何将InMemoryRandomAccessStream转换为WPF的BitmapImage
在WPF中使用UWP MediaCapture获取WPF BitmapImage的解决方案
方法一:直接从MediaCapture捕获流转换为WPF BitmapImage
通过将UWP的InMemoryRandomAccessStream转换为.NET标准MemoryStream,再用WPF的BitmapImage加载,是最直接的实现方式:
using System.IO; using Windows.Media.Capture; using Windows.Media.MediaProperties; using Windows.Storage.Streams; using System.Windows.Media.Imaging; // 前提:_mediaCapture已完成初始化且获得摄像头权限 using var uwpStream = new InMemoryRandomAccessStream(); await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), uwpStream); uwpStream.Seek(0); // 转换UWP流为.NET MemoryStream using var netStream = new MemoryStream(); await uwpStream.AsStreamForRead().CopyToAsync(netStream); netStream.Seek(0, SeekOrigin.Begin); // 创建并加载WPF BitmapImage var wpfBitmap = new BitmapImage(); wpfBitmap.BeginInit(); wpfBitmap.CacheOption = BitmapCacheOption.OnLoad; // 确保流关闭后图像仍可用 wpfBitmap.StreamSource = netStream; wpfBitmap.EndInit(); wpfBitmap.Freeze(); // 非UI线程使用时需要冻结,保证线程安全
方法二:将已有的UWP BitmapImage转换为WPF BitmapImage
如果已经持有UWP的BitmapImage实例,可以通过提取像素数据重新编码的方式转换:
using System.IO; using Windows.UI.Xaml.Media.Imaging; using Windows.Graphics.Imaging; using System.Windows.Media.Imaging; // 假设uwpBitmap是已创建的UWP BitmapImage using var uwpStream = new InMemoryRandomAccessStream(); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, uwpStream); // 提取UWP BitmapImage的像素数据 var pixelBuffer = await uwpBitmap.PixelBuffer.ToArrayAsync(); encoder.SetPixelData( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)uwpBitmap.PixelWidth, (uint)uwpBitmap.PixelHeight, 96, 96, // DPI参数,可根据需求调整 pixelBuffer); await encoder.FlushAsync(); uwpStream.Seek(0); // 后续转换逻辑同方法一 using var netStream = new MemoryStream(); await uwpStream.AsStreamForRead().CopyToAsync(netStream); netStream.Seek(0, SeekOrigin.Begin); var wpfBitmap = new BitmapImage(); wpfBitmap.BeginInit(); wpfBitmap.CacheOption = BitmapCacheOption.OnLoad; wpfBitmap.StreamSource = netStream; wpfBitmap.EndInit(); wpfBitmap.Freeze();
关键注意事项
- 必须确保
MediaCapture已完成初始化流程,并且应用已获得摄像头访问权限 - 设置
BitmapCacheOption.OnLoad是核心:WPF的BitmapImage默认懒加载,流关闭后会丢失数据,该配置会在初始化时加载全部数据 - 若需在非UI线程使用
BitmapImage,必须调用Freeze()使其变为只读,避免线程安全问题
内容的提问来源于stack exchange,提问作者LYCRIs
相关产品推荐
相关产品推荐

