马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
传统的方法比较多,很多是重新天生一个Bitmap再赋值,其实这步可以略做简化。- public static void DrawImage(this Avalonia.Controls.Image uiimg, Image<Rgb24> imageSharpImage)
- {
- //首先要用到他的tag对象
- var width = imageSharpImage.Width;
- var height = imageSharpImage.Height;
- WriteableBitmap wbmp = null;
- if (uiimg.Tag is WriteableBitmap oldwbmp)
- {
- //如果宽高不等,就重新创建
- if (oldwbmp.PixelSize.Width != width || oldwbmp.PixelSize.Height != height)
- {
- uiimg.Source = null;
- oldwbmp.Dispose();
- uiimg.Tag = null;
- wbmp = new WriteableBitmap(new PixelSize(width, height), new Vector(96, 96),
- PixelFormat.Rgba8888, AlphaFormat.Premul);
- uiimg.Tag = wbmp;
- uiimg.Source = wbmp;
- }
- else
- {
- //否则直接赋值
- wbmp = oldwbmp;
- }
- }
- else
- {
- //没有也是重新创建
- wbmp = new WriteableBitmap(new PixelSize(width, height), new Vector(96, 96),
- PixelFormat.Rgba8888, AlphaFormat.Premul);
- uiimg.Tag = wbmp;
- uiimg.Source = wbmp;
- }
- using var rgba32img = imageSharpImage.CloneAs<Rgba32>();
- if (rgba32img.DangerousTryGetSinglePixelMemory(out var memory))
- {
- // 3. 锁住内存,直接进行内存块高速拷贝(零解码开销)
- using (var handle = memory.Pin())
- using (var lockedBuffer = wbmp.Lock())
- {
- unsafe
- {
- long totalBytes = width * height * 4;
- // 使用 Buffer.MemoryCopy 高速复制内存
- Buffer.MemoryCopy(handle.Pointer, (void*)lockedBuffer.Address, totalBytes, totalBytes);
- }
- }
- uiimg.InvalidateVisual();
- }
- else
- {
- Log.Error("无法获取 ImageSharp 的连续内存缓冲区。");
- }
- }
复制代码 代码比较简朴,利用rgb8888是因为写代码相对简朴,否复制的时候得考虑更多的东西,这样做还有个条件是sixlabor的image需要连续,这个可以在启动的时候- Configuration.Default.PreferContiguousImageBuffers = true; 进行配置。<br>wpf应该也差不多。当时还想到用两个writeablebitmap进行swap,avalonia可以在其他线程渲染好bitmap,再到前台线程赋值 给image,按理也是可以的。<br>最后:没有实测效率和内存占用。
复制代码 |