Skip to content

Commit 34e8153

Browse files
committed
Added Get-OCR
Runs Windows 10 OCR on an image.
1 parent a8660a4 commit 34e8153

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

media/Get-OCR.ps1

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Credits https://github.com/HumanEquivalentUnit/PowerShell-Misc/blob/master/Get-Win10OcrTextFromImage.ps1
2+
3+
function Get-OCR {
4+
<#
5+
.SYNOPSIS
6+
Runs Windows 10 OCR on an image.
7+
8+
.DESCRIPTION
9+
Takes a path to an image file, with some text on it.
10+
Runs Windows 10 OCR against the image.
11+
Returns an [OcrResult], hopefully with a .Text property containing the text
12+
13+
.PARAMETER -Path
14+
Path to an image file
15+
16+
.EXAMPLE
17+
Get-OCR -Path 'c:\test.bmp'
18+
#>
19+
[CmdletBinding()]
20+
param(
21+
[Parameter(Mandatory = $true,
22+
ValueFromPipeline = $true,
23+
ValueFromPipelineByPropertyName = $true,
24+
Position = 0,
25+
HelpMessage = 'Path to an image file, to run OCR on')]
26+
[ValidateNotNullOrEmpty()]
27+
$Path
28+
)
29+
30+
Begin {
31+
# Add the WinRT assembly, and load the appropriate WinRT types
32+
Add-Type -AssemblyName System.Runtime.WindowsRuntime
33+
34+
$null = [Windows.Storage.StorageFile, Windows.Storage, ContentType = WindowsRuntime]
35+
$null = [Windows.Media.Ocr.OcrEngine, Windows.Foundation, ContentType = WindowsRuntime]
36+
$null = [Windows.Foundation.IAsyncOperation`1, Windows.Foundation, ContentType = WindowsRuntime]
37+
$null = [Windows.Graphics.Imaging.SoftwareBitmap, Windows.Foundation, ContentType = WindowsRuntime]
38+
$null = [Windows.Storage.Streams.RandomAccessStream, Windows.Storage.Streams, ContentType = WindowsRuntime]
39+
40+
# [Windows.Media.Ocr.OcrEngine]::AvailableRecognizerLanguages
41+
$ocrEngine = [Windows.Media.Ocr.OcrEngine]::TryCreateFromUserProfileLanguages()
42+
43+
# PowerShell doesn't have built-in support for Async operations,
44+
# but all the WinRT methods are Async.
45+
# This function wraps a way to call those methods, and wait for their results.
46+
$getAwaiterBaseMethod = [WindowsRuntimeSystemExtensions].GetMember('GetAwaiter').
47+
Where({
48+
$PSItem.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1'
49+
}, 'First')[0]
50+
51+
Function Await {
52+
param($AsyncTask, $ResultType)
53+
54+
$getAwaiterBaseMethod.
55+
MakeGenericMethod($ResultType).
56+
Invoke($null, @($AsyncTask)).
57+
GetResult()
58+
}
59+
}
60+
61+
Process {
62+
foreach ($p in $Path) {
63+
# From MSDN, the necessary steps to load an image are:
64+
# Call the OpenAsync method of the StorageFile object to get a random access stream containing the image data.
65+
# Call the static method BitmapDecoder.CreateAsync to get an instance of the BitmapDecoder class for the specified stream.
66+
# Call GetSoftwareBitmapAsync to get a SoftwareBitmap object containing the image.
67+
#
68+
# https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/imaging#save-a-softwarebitmap-to-a-file-with-bitmapencoder
69+
70+
# .Net method needs a full path, or at least might not have the same relative path root as PowerShell
71+
$p = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p)
72+
73+
$params = @{
74+
AsyncTask = [Windows.Storage.StorageFile]::GetFileFromPathAsync($p)
75+
ResultType = [Windows.Storage.StorageFile]
76+
}
77+
$storageFile = Await @params
78+
79+
80+
$params = @{
81+
AsyncTask = $storageFile.OpenAsync([Windows.Storage.FileAccessMode]::Read)
82+
ResultType = [Windows.Storage.Streams.IRandomAccessStream]
83+
}
84+
$fileStream = Await @params
85+
86+
87+
$params = @{
88+
AsyncTask = [Windows.Graphics.Imaging.BitmapDecoder]::CreateAsync($fileStream)
89+
ResultType = [Windows.Graphics.Imaging.BitmapDecoder]
90+
}
91+
$bitmapDecoder = Await @params
92+
93+
94+
$params = @{
95+
AsyncTask = $bitmapDecoder.GetSoftwareBitmapAsync()
96+
ResultType = [Windows.Graphics.Imaging.SoftwareBitmap]
97+
}
98+
$softwareBitmap = Await @params
99+
100+
# Run the OCR
101+
Await $ocrEngine.RecognizeAsync($softwareBitmap) ([Windows.Media.Ocr.OcrResult])
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)