This commit is contained in:
tanglong 2025-09-17 11:55:58 +08:00
parent f0662fbda7
commit e95b792fef
2 changed files with 85 additions and 1 deletions

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows;
namespace Wpf_AiSportsMicrospace
{
public class D3DFrameRenderer
{
private D3DImage _d3dImage;
public D3DFrameRenderer(D3DImage d3dImage)
{
_d3dImage = d3dImage;
}
// 当有新帧时调用
public void RenderFrame(byte[] jpegBuffer)
{
Task.Run(() =>
{
int width, height;
var bgra = ConvertJpegToBGRA32(jpegBuffer, out width, out height);
// 更新 UI
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
if (!_d3dImage.IsFrontBufferAvailable) return;
if (_d3dImage.PixelWidth != width || _d3dImage.PixelHeight != height)
{
_d3dImage.Lock();
_d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero); // 先清空
_d3dImage.Unlock();
}
// 用 WriteableBitmap 临时显示
var wb = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);
wb.Lock();
Marshal.Copy(bgra, 0, wb.BackBuffer, bgra.Length);
wb.AddDirtyRect(new Int32Rect(0, 0, width, height));
wb.Unlock();
_d3dImage.Lock();
_d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero); // 暂时不绑定真实 D3D Surface
_d3dImage.Unlock();
// 临时用 ImageSource 显示
FrameReady?.Invoke(wb, width, height);
}));
});
}
public delegate void FrameReadyHandler(ImageSource frame, int width, int height);
public event FrameReadyHandler FrameReady;
private byte[] ConvertJpegToBGRA32(byte[] jpegBuffer, out int width, out int height)
{
using var ms = new MemoryStream(jpegBuffer);
using var bmp = new Bitmap(ms);
width = bmp.Width;
height = bmp.Height;
var rect = new Rectangle(0, 0, width, height);
var bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
int bytes = bmpData.Stride * height;
byte[] raw = new byte[bytes];
Marshal.Copy(bmpData.Scan0, raw, 0, bytes);
bmp.UnlockBits(bmpData);
return raw;
}
}
}

View File

@ -185,7 +185,7 @@ public partial class MainWindow : Window
// UI 线程显示 // UI 线程显示
Application.Current.Dispatcher.Invoke(() => Application.Current.Dispatcher.Invoke(() =>
{ {
if (videoImage == null) return; if (videoImage == null ) return;
if (_videoBitmap == null || if (_videoBitmap == null ||
_videoBitmap.PixelWidth != bitmap.PixelWidth || _videoBitmap.PixelWidth != bitmap.PixelWidth ||