Я пытаюсь получить текст фигуры рисунка в Microsoft Word. Для этого я использую библиотеку OCR, которая включена в Windows 10 windows.media.ocr
. Поскольку для OCREngine
нужен SoftwareBitmap
, с которым я еще не работал, я попробовал следующий подход, чтобы добраться до этого SoftwareBitmap
:
oWordDocument.Shapes(1).Select() '*** Get shape and copy to clipboard and then to bitmap
oWordApp.Selection.CopyAsPicture()
Dim oBitmap As System.Drawing.Bitmap = New System.Drawing.Bitmap(System.Windows.Forms.Clipboard.GetImage())
Dim oSoftwareBitmap As Windows.Graphics.Imaging.SoftwareBitmap
Dim oUWPStream As Windows.Storage.Streams.IRandomAccessStream
Using oNetStream As New System.IO.MemoryStream '*** Get UWP-Stream via .Net-Stream
oBitmap.Save(oNetStream, System.Drawing.Imaging.ImageFormat.Png)
oUWPStream = System.IO.WindowsRuntimeStreamExtensions.AsRandomAccessStream(oNetStream)
'*** in the following line an invalidcast error occurs "Unable to cast object of type 'System.__ComObject' to type 'Windows.Graphics.Imaging.BitmapDecoder'."
Dim oBitmapDecoder As Windows.Graphics.Imaging.BitmapDecoder = Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(Windows.Graphics.Imaging.BitmapDecoder.PngDecoderId, oUWPStream)
oSoftwareBitmap = oBitmapDecoder.GetSoftwareBitmapAsync()
End Using
Итак, сейчас код работает нормально, пока я не попытаюсь создать BitmapDecoder. Из того, что я вижу, я предоставляю действительный RandomAccessStream, но создание не выполняется с недействительным.
Может ли кто-нибудь помочь в этом или даже предоставить или указать мне образец кода для создания BitmapDecoder и SoftwareBitmap?
Извините, если описание сложное или запутанное - английский не мой родной язык
Проблема решена: на самом деле решение было довольно простым. Я просто не понял этого с первого раза. Я с самого начала знал, что мне следовало использовать await с асинхронными методами, но я всегда сталкивался с не очень полезными сообщениями об ошибках от визуального редактора. И это было просто из-за отсутствия асинхронного контекста. После того, как я добавил ключевое слово async в свой обработчик событий Private Async Sub SelectFilesButton_Click(sender As Object, e As EventArgs) Handles SelectFilesButton.Click
, все прошло нормально, и я мог использовать оператор await, как ожидалось.
Вот окончательное решение, соответствующее приведенному выше коду:
'*** Get Bitmap from Word Bitmap-Shape
oWordDocument.Shapes(1).Select()
oWordApp.Selection.CopyAsPicture()
Dim oBitmap As System.Drawing.Bitmap = New System.Drawing.Bitmap(System.Windows.Forms.Clipboard.GetImage())
'*** Convert Streams, get BitmapDecoder + SoftwareBitmap
Using oNetStream As New System.IO.MemoryStream
oBitmap.Save(oNetStream, System.Drawing.Imaging.ImageFormat.Png)
Dim oUWPStream As Windows.Storage.Streams.IRandomAccessStream = System.IO.WindowsRuntimeStreamExtensions.AsRandomAccessStream(oNetStream)
Dim oBitmapDecoder As Windows.Graphics.Imaging.BitmapDecoder = Await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(oUWPStream)
Dim oSoftwareBitmap As Windows.Graphics.Imaging.SoftwareBitmap = Await oBitmapDecoder.GetSoftwareBitmapAsync()
End Using
Спасибо, Джими, что указал мне в правильном направлении - извини, что мне потребовалось столько времени, чтобы понять
PS: Очень помогли понять, что это были 2 статьи из руководств по программированию Microsoft, которые вы можете найти, используя следующие условия поиска: «Поток управления в асинхронных программах (Visual Basic)» и «Асинхронное программирование с использованием Async и Await (Visual Basic)»
Привет, Синди, спасибо за помощь. Я внес некоторые изменения в вопрос. Моя текущая проблема, похоже, связана с созданием BitmapDecoder или SoftwareBitmap. Проблема связана не только с Word. Word - это всего лишь одна из возможных сред, в которой могут храниться данные растрового изображения, которые могут использоваться Ocr-Engine. Я знаком с офисной объектной моделью, создав приложения VSTO, но ничего не знаю о части UWP.
BitmapDecoder.CreateAsync()
возвращает IAsyncOperation<BitmapDecoder>
. Вы должны await CreateAsync()
в контексте async (метод async).
Привет, Джими, спасибо за помощь. Я тоже думал о том, что это проблема. Я просто не мог найти источник, где я мог бы найти, как это сделать в VB.Net. Вы знаете что-нибудь или могли бы предоставить дополнительную информацию?
Что делать в VB? Асинхронный метод?
Да - когда я использую async, мне нужно много чего, чего я сейчас не понимаю. В C# это выглядит так просто ...
Асинхронные методы VB.Net и C# абсолютно одинаковы. Меняется только позиция объявления типа. C# => private async Task<int> MyMethodAsync() { return await SomeMethodWhichReturnsIntAsync(); }
VB: Private Async Function MyMethodAsync() As Task(Of Integer) Return Await SomeMethodWhichReturnsIntAsync() End Function
. Вы можете вызвать асинхронный метод из другого асинхронного метода, если вам нужно дождаться результатов, или использовать асинхронный метод прокси из неасинхронного метода для вызова асинхронного метода вашего рабочего (когда вы хотите запустить асинхронный процесс с запуском и забыть, потому что результатов ждать не нужно).
Извини, Джими - я не могу понять, как использовать эту информацию в моем случае. Я все еще не могу написать код, который создает объект BitmapDecoder, а затем объект SoftwareBitmap.
FWIW существует три способа извлечения графического изображения из Word: буфер обмена (то, что у вас есть), метод сохранения как изображения, извлечение изображения из WordOpenXML. Через буфер обмена, наверное, неплохо, потому что вы можете запрашивать информацию в нужном вам графическом формате. Обратите внимание, что если к Фигуре был добавлен текст, отредактировав его из в Word, вы можете извлечь этот текст непосредственно с помощью объектной модели.