猿问

快速将位图转换为BitmapSource wpf

我需要以Image30Hz的频率在组件上绘制图像。我使用此代码:


public MainWindow()

    {

        InitializeComponent();


        Messenger.Default.Register<Bitmap>(this, (bmp) =>

        {

            ImageTarget.Dispatcher.BeginInvoke((Action)(() =>

            {

                var hBitmap = bmp.GetHbitmap();

                var drawable = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(

                  hBitmap,

                  IntPtr.Zero,

                  Int32Rect.Empty,

                  BitmapSizeOptions.FromEmptyOptions());

                DeleteObject(hBitmap);

                ImageTarget.Source = drawable;

            }));

        });

    }

问题是,使用此代码,我的CPU使用率约为80%,而没有转换,则约为6%。


那为什么转换位图这么长呢?

是否有更快的方法(使用不安全的代码)?


慕的地10843
浏览 692回答 2
2回答

蛊毒传说

根据我的经验,这是一种比至少快四倍的方法CreateBitmapSourceFromHBitmap。它要求您设置正确PixelFormat的结果BitmapSource。public BitmapSource Convert(System.Drawing.Bitmap bitmap){&nbsp; &nbsp; var bitmapData = bitmap.LockBits(&nbsp; &nbsp; &nbsp; &nbsp; new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),&nbsp; &nbsp; &nbsp; &nbsp; System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);&nbsp; &nbsp; var bitmapSource = BitmapSource.Create(&nbsp; &nbsp; &nbsp; &nbsp; bitmapData.Width, bitmapData.Height,&nbsp; &nbsp; &nbsp; &nbsp; bitmap.HorizontalResolution, bitmap.VerticalResolution,&nbsp; &nbsp; &nbsp; &nbsp; PixelFormats.Bgr24, null,&nbsp; &nbsp; &nbsp; &nbsp; bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);&nbsp; &nbsp; bitmap.UnlockBits(bitmapData);&nbsp; &nbsp; return bitmapSource;}

呼啦一阵风

在克莱门斯回答之前,我回答了自己:[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);&nbsp;WriteableBitmap writeableBitmap = new WriteableBitmap(1280, 1024, 96.0, 96.0, PixelFormats.Bgr24, null);&nbsp; &nbsp; &nbsp; &nbsp; public MainWindow()&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ImageTarget.Source = writeableBitmap;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Messenger.Default.Register<Bitmap>(this, (bmp) =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ImageTarget.Dispatcher.BeginInvoke((Action)(() =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writeableBitmap.Lock();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CopyMemory(writeableBitmap.BackBuffer, data.Scan0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (writeableBitmap.BackBufferStride * bmp.Height));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, bmp.Width, bmp.Height));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writeableBitmap.Unlock();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bmp.UnlockBits(data);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; }现在我的CPU使用率约为15%
随时随地看视频慕课网APP
我要回答