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

传统的方法比较多,很多是重新生成一个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; 进行配置。
wpf应该也差不多。当时还想到用两个writeablebitmap进行swap,avalonia可以在其他线程渲染好bitmap,再到前台线程赋值 给image,按理也是可以的。
最后:没有实测效率和内存占用。
posted @ 2026-08-13 09:37  首席装逼官  阅读(2)  评论(0)    收藏  举报