在Avalonia(wpf应该原理一样)中怎么快速的把视频或者画面渲染到image

[复制链接]
发表于 2026-8-13 10:16:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
传统的方法比较多,很多是重新天生一个Bitmap再赋值,其实这步可以略做简化。
  1. public static void DrawImage(this Avalonia.Controls.Image uiimg, Image<Rgb24> imageSharpImage)
  2.     {
  3.         //首先要用到他的tag对象
  4.         var width = imageSharpImage.Width;
  5.         var height = imageSharpImage.Height;
  6.         WriteableBitmap wbmp = null;
  7.         if (uiimg.Tag is WriteableBitmap oldwbmp)
  8.         {
  9.             //如果宽高不等,就重新创建
  10.             if (oldwbmp.PixelSize.Width != width || oldwbmp.PixelSize.Height != height)
  11.             {
  12.                 uiimg.Source = null;
  13.                 oldwbmp.Dispose();
  14.                 uiimg.Tag = null;
  15.                 wbmp = new WriteableBitmap(new PixelSize(width, height), new Vector(96, 96),
  16.                     PixelFormat.Rgba8888, AlphaFormat.Premul);
  17.                 uiimg.Tag = wbmp;
  18.                 uiimg.Source = wbmp;
  19.             }
  20.             else
  21.             {
  22.                 //否则直接赋值
  23.                 wbmp = oldwbmp;
  24.             }
  25.         }
  26.         else
  27.         {
  28.             //没有也是重新创建
  29.             wbmp = new WriteableBitmap(new PixelSize(width, height), new Vector(96, 96),
  30.                 PixelFormat.Rgba8888, AlphaFormat.Premul);
  31.             uiimg.Tag = wbmp;
  32.             uiimg.Source = wbmp;
  33.         }
  34.         using var rgba32img = imageSharpImage.CloneAs<Rgba32>();
  35.         if (rgba32img.DangerousTryGetSinglePixelMemory(out var memory))
  36.         {
  37.             // 3. 锁住内存,直接进行内存块高速拷贝(零解码开销)
  38.             using (var handle = memory.Pin())
  39.             using (var lockedBuffer = wbmp.Lock())
  40.             {
  41.                 unsafe
  42.                 {
  43.                     long totalBytes = width * height * 4;
  44.                     // 使用 Buffer.MemoryCopy 高速复制内存
  45.                     Buffer.MemoryCopy(handle.Pointer, (void*)lockedBuffer.Address, totalBytes, totalBytes);
  46.                 }
  47.             }
  48.             uiimg.InvalidateVisual();
  49.         }
  50.         else
  51.         {
  52.             Log.Error("无法获取 ImageSharp 的连续内存缓冲区。");
  53.         }
  54.     }
复制代码
代码比较简朴,利用rgb8888是因为写代码相对简朴,否复制的时候得考虑更多的东西,这样做还有个条件是sixlabor的image需要连续,这个可以在启动的时候
  1. Configuration.Default.PreferContiguousImageBuffers = true; 进行配置。<br>wpf应该也差不多。当时还想到用两个writeablebitmap进行swap,avalonia可以在其他线程渲染好bitmap,再到前台线程赋值 给image,按理也是可以的。<br>最后:没有实测效率和内存占用。
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表