VB.NET如何创建BitmapDecoder与SoftwareBitmap?Word图片形状OCR文本提取
嘿,我刚好折腾过类似的需求,来给你一步步拆解怎么实现从Word形状提取文本的完整流程,重点解决你问到的BitmapDecoder和SoftwareBitmap创建问题!
从Word形状提取文本(VB.NET + Windows.Media.OCR)
第一步:把Word里的形状复制成图片到剪贴板
先把你已经写的代码补全,确保能正确选中形状并复制为图片:
' 初始化Word应用和文档(记得后续要释放资源哦) Dim oWordApp As New Microsoft.Office.Interop.Word.Application() Dim oWordDocument As Microsoft.Office.Interop.Word.Document = oWordApp.Documents.Open("你的Word文档路径.docx") ' 选中第一个形状并复制为图片格式 oWordDocument.Shapes(1).Select() oWordApp.Selection.CopyAsPicture()
第二步:从剪贴板拿到System.Drawing.Bitmap
这一步要先判断剪贴板里有没有图片内容,避免报错:
Dim oBitmap As System.Drawing.Bitmap = Nothing If Clipboard.ContainsImage() Then oBitmap = DirectCast(Clipboard.GetImage(), System.Drawing.Bitmap) Else MessageBox.Show("剪贴板里没找到图片内容哦") ' 这里可以加个退出逻辑 Return End If
第三步:把System.Drawing.Bitmap转成SoftwareBitmap(重点!)
这就是你要的核心步骤——因为Windows.Media.OCR的OcrEngine只认WinRT的SoftwareBitmap,而我们从剪贴板拿到的是GDI+的System.Drawing.Bitmap,得用WIC(Windows Imaging Component)的解码器来转换:
首先,你的项目需要添加几个引用:WindowsBase、PresentationCore和System.Xaml(如果是WinForms项目,右键项目→添加引用→框架里找这几个)。
然后写转换函数:
Imports System.IO Imports System.Windows.Media.Imaging Imports Windows.Media Private Function ConvertDrawingBitmapToSoftwareBitmap(drawingBitmap As System.Drawing.Bitmap) As SoftwareBitmap ' 先把GDI+ Bitmap存到内存流里 Using ms As New MemoryStream() drawingBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png) ms.Position = 0 ' 把流指针移回开头 ' 创建BitmapDecoder,读取内存流里的图片 Dim decoder As BitmapDecoder = BitmapDecoder.Create(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default) ' 取第一帧(因为我们的图片是单帧的),转成SoftwareBitmap Dim firstFrame As BitmapFrame = decoder.Frames(0) Return SoftwareBitmap.CreateCopyFromBuffer(firstFrame.PixelBuffer, firstFrame.Format, firstFrame.PixelWidth, firstFrame.PixelHeight) End Using End Function
第四步:用SoftwareBitmap做OCR识别
拿到SoftwareBitmap后,就可以调用OCR引擎了:
Imports Windows.Media.Ocr ' 先把刚才的Bitmap转成SoftwareBitmap Dim targetSoftwareBitmap = ConvertDrawingBitmapToSoftwareBitmap(oBitmap) ' 检查目标语言是否支持OCR(这里用中文举例,换成你需要的语言,比如en-US) Dim targetLang = Windows.Globalization.Language.GetLanguage("zh-CN") If OcrEngine.IsLanguageSupported(targetLang) Then Dim ocrEngine = OcrEngine.TryCreateFromLanguage(targetLang) ' 异步识别,记得用Await Dim ocrResult = Await ocrEngine.RecognizeAsync(targetSoftwareBitmap) ' 拿到识别后的文本 Dim recognizedText = ocrResult.Text MessageBox.Show("识别结果:" & vbCrLf & recognizedText) Else MessageBox.Show("当前系统不支持该语言的OCR识别") End If
一些要注意的小细节
- 用完Word对象后记得释放资源,避免进程残留:
oWordDocument.Close()、oWordApp.Quit(),还要用Marshal.ReleaseComObject清理。 - 剪贴板操作尽量在UI线程里做,避免跨线程问题。
- 可以通过
OcrEngine.AvailableRecognizerLanguages获取当前系统支持的所有OCR语言。
内容的提问来源于stack exchange,提问作者Oliver Brehm
相关产品推荐
相关产品推荐

