我目前在一个项目中,我正在从IP摄像机接收实时视频流作为MediaPlayer对象。最终目标是能够使用Windows.Media.OCR每秒钟左右从框架中提取文本,为此,我需要一个SoftwareBitmap。
从Microsoft UWP文档看来,可以使用CopyFrameToVideoSurface(CanvasBitmap)方法从MediaPlayer对象获取帧。我可以从SoftwareBitmap创建CanvasBitmap,但是我没有找到一种无需保存文件就可以从CanvasBitmap创建SoftwareBitmap的方法(我试图避免这种情况,不需要保留图像)。我希望我缺少一些简单的东西,有没有办法从MediaPlayer对象获取SoftwareBitmap?
我一直在引用this example在帧服务器模式下使用MediaPlayer。我不需要显示图像,因此,如果可能的话,最好避免使用CanvasBitmap。
媒体播放器
private async Task GetStream()
{
mediaPlayer = new MediaPlayer()
{
Source = MediaSource.CreateFromStream(placeholder, "video")
};
mediaPlayer.VideoFrameAvailable += VideoFrameAvailable;
mediaPlayer.IsVideoFrameServerEnabled = true;
mediaPlayer.Play();
}
private async void VideoFrameAvailable(MediaPlayer sender, object args)
{
// Get frame from media player, create SoftwareBitmap
await ExtractText(softwareBitmapImg);
}
我提供的OCR部分的代码相对简单,当我提供SoftwareBitmap时,它就像一个魅力。
光学字符识别
private async Task ExtractText()
{
Language ocrLanguage = new Language("en-us");
OcrEngine ocrEngine = OcrEngine.TryCreateFromLanguage(ocrLanguage);
var ocrResult = await ocrEngine.RecognizeAsync(bitmap);
String text = ocrResult.Text;
}
最佳答案
CanvasBitmap实现IDirect3DSurface接口,只要调用VideoFrameAvailable处理程序,就使用CopyFrameToVideoSurface方法将帧的内容复制到IDirect3DSurface。当调用CopyFrameToVideoSurface时,我们需要CanvasBitmap对象将当前帧从MediaPlayer复制到CanvasBitmap中,但是您无需显示图像。
private async void mediaPlayer_VideoFrameAvailable(MediaPlayer sender, object args)
{
CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
SoftwareBitmap softwareBitmapImg;
SoftwareBitmap frameServerDest = new SoftwareBitmap(BitmapPixelFormat.Rgba8, 100, 100, BitmapAlphaMode.Premultiplied);
using (CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(canvasDevice, frameServerDest))
{
sender.CopyFrameToVideoSurface(canvasBitmap);
softwareBitmapImg = await SoftwareBitmap.CreateCopyFromSurfaceAsync(canvasBitmap);
}
await ExtractText(softwareBitmapImg);
});
}