Skip to content

Commit

Permalink
Add OCR support (including text, bar codes and QR codes) on the "Imag…
Browse files Browse the repository at this point in the history
…e" tab for Windows 10, 11
  • Loading branch information
AlexanderPro committed Nov 16, 2022
1 parent 8e8b07a commit 28dfce3
Show file tree
Hide file tree
Showing 13 changed files with 623 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Build/Build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<WindowTextExtractorDestFileWin64 Include="$(ApplicationPath)\WindowTextExtractor64.exe" />
<WindowTextExtractorSourceConfgiFile Include="$(WindowTextExtractorProjectPath)\bin\x86\Release\WindowTextExtractor.exe.config" />
<WindowTextExtractorDestConfgiFile Include="$(ApplicationPath)\WindowTextExtractor.exe.config" />
<WindowTextExtractorSourceLibFiles Include="$(WindowTextExtractorProjectPath)\bin\x86\Release\Libs\*.dll" />
<WindowTextExtractorSourceLibFiles Include="$(WindowTextExtractorProjectPath)\bin\x86\Release\*.dll" />
<WindowTextExtractorDestLibFiles Include="$(ApplicationPath)\" />
</ItemGroup>

Expand Down
6 changes: 3 additions & 3 deletions WindowTextExtractor/App.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
</configuration>
</configuration>
74 changes: 74 additions & 0 deletions WindowTextExtractor/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

namespace WindowTextExtractor.Extensions
{
Expand All @@ -13,5 +14,78 @@ public static string TrimEnd(this string text, string value, StringComparison co
}
return result;
}

public static string TryFixEveryWordLetterNumberErrors(this string text)
{
var listOfWords = text.Split(' ');
var fixedWords = new List<string>();

foreach (var word in listOfWords)
{
var newWord = word.TryFixNumberLetterErrors();
fixedWords.Add(newWord);
}

return string.Join(" ", fixedWords.ToArray())
.Replace("\t ", "\t")
.Replace("\r ", "\r")
.Replace("\n ", "\n")
.Trim();
}

public static string TryFixNumberLetterErrors(this string text)
{
if (text.Length < 5)
{
return text;
}

var totalNumbers = 0;
var totalLetters = 0;

foreach (char charFromString in text)
{
if (char.IsNumber(charFromString))
{
totalNumbers++;
}

if (char.IsLetter(charFromString))
{
totalLetters++;
}
}

var fractionNumber = totalNumbers / (float)text.Length;
var letterNumber = totalLetters / (float)text.Length;

if (fractionNumber > 0.6)
{
text = text.TryFixToNumbers();
}
else if (letterNumber > 0.6)
{
text = text.TryFixToLetters();
}

return text;
}

public static string TryFixToNumbers(this string text) => text
.Replace('o', '0')
.Replace('O', '0')
.Replace('Q', '0')
.Replace('c', '0')
.Replace('C', '0')
.Replace('i', '1')
.Replace('I', '1')
.Replace('l', '1')
.Replace('g', '9');

public static string TryFixToLetters(this string text) => text
.Replace('0', 'o')
.Replace('4', 'h')
.Replace('9', 'g')
.Replace('1', 'l');
}
}
235 changes: 140 additions & 95 deletions WindowTextExtractor/Forms/MainForm.Designer.cs

Large diffs are not rendered by default.

73 changes: 71 additions & 2 deletions WindowTextExtractor/Forms/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Text;
using System.Linq;
using System.Xml.Linq;
using Windows.Media.Ocr;
using WindowTextExtractor.Extensions;
using WindowTextExtractor.Utils;
using WindowTextExtractor.Diagnostics;
Expand Down Expand Up @@ -115,6 +116,14 @@ protected override void OnLoad(EventArgs e)
font.Dispose();
}

try
{
BindLanguages();
}
catch
{
}

#if WIN32
if (Environment.Is64BitOperatingSystem)
{
Expand Down Expand Up @@ -433,7 +442,18 @@ private void btnRecord_Click(object sender, EventArgs e)
_startRecordingTime = _isRecording ? DateTime.Now : (DateTime?)null;
if (_isRecording)
{
_videoWriter.Open(_videoFileName, _image.Width, _image.Height, _fps, VideoCodec.Raw);
try
{
_videoWriter.Open(_videoFileName, _image.Width, _image.Height, _fps, VideoCodec.Raw);
}
catch (Exception ex)
{
_startRecordingTime = null;
_isRecording = false;
_videoWriter.Close();
MessageBox.Show($"Failed to start recording a video file. {ex.Message}", AssemblyUtils.AssemblyTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else
{
Expand All @@ -446,13 +466,52 @@ private void btnRecord_Click(object sender, EventArgs e)
button.Text = isRecording ? "Stop" : "Record";
btnTarget.Enabled = !isRecording;
btnShowHide.Enabled = !isRecording;
btnGrab.Enabled = !isRecording;
cmbRefresh.Enabled = !isRecording;
cmbCaptureCursor.Enabled = !isRecording;
cmbLanguages.Enabled = !isRecording;
btnBrowseFile.Enabled = !isRecording;
numericFps.Enabled = !isRecording;
numericScale.Enabled = !isRecording;
}

private void btnGrab_Click(object sender, EventArgs e)
{
lock (_lockObject)
{
if (!_isRecording)
{
var text = string.Empty;
try
{
text = ImageUtils.ExtractTextAsync((Bitmap)_image.Clone(), cmbLanguages.SelectedValue as string).GetAwaiter().GetResult();
var barcodes = ImageUtils.ExtractBarcodes((Bitmap)_image.Clone());
if (!string.IsNullOrEmpty(barcodes))
{
text += Environment.NewLine + barcodes;
}
}
catch (Exception ex)
{
MessageBox.Show($"Failed to recognize a text in the image. {ex.Message}", AssemblyUtils.AssemblyTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

if (string.IsNullOrEmpty(text))
{
MessageBox.Show("Text is not found in the image.", AssemblyUtils.AssemblyTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
txtContent.Text = text;
txtContent.ScrollTextToEnd();
AddTextToList(text);
tabContent.SelectedTab = tabpText;
}
}
}
}

private void btnBrowseFile_Click(object sender, EventArgs e)
{
var dialog = new SaveFileDialog
Expand Down Expand Up @@ -798,8 +857,11 @@ private void InitTimers(int fps)
private void EnableImageTabControls()
{
btnRecord.Visible = _imageTab && btnShowHide.Visible;
btnGrab.Visible = _imageTab && btnShowHide.Visible;
lblRefresh.Visible = _imageTab && btnShowHide.Visible;
cmbRefresh.Visible = _imageTab && btnShowHide.Visible;
lblLanguages.Visible = _imageTab && btnShowHide.Visible;
cmbLanguages.Visible = _imageTab && btnShowHide.Visible;
lblCaptureCursor.Visible = _imageTab && btnShowHide.Visible;
cmbCaptureCursor.Visible = _imageTab && btnShowHide.Visible;
lblFps.Visible = _imageTab && btnShowHide.Visible;
Expand Down Expand Up @@ -917,6 +979,13 @@ private void AddTextToList(string text)
gvTextList.FirstDisplayedScrollingRowIndex = index;
}

private void BindLanguages()
{
cmbLanguages.DisplayMember = "Text";
cmbLanguages.ValueMember = "Value";
cmbLanguages.DataSource = OcrEngine.AvailableRecognizerLanguages.Select(x => new { Text = x.DisplayName, Value = x.LanguageTag }).ToList();
}

private void OnCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
Expand All @@ -925,6 +994,6 @@ private void OnCurrentDomainUnhandledException(object sender, UnhandledException
}

private void OnThreadException(object sender, ThreadExceptionEventArgs e) =>
MessageBox.Show(e.Exception.ToString(), AssemblyUtils.AssemblyTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(e.Exception.Message, AssemblyUtils.AssemblyTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
16 changes: 8 additions & 8 deletions WindowTextExtractor/Forms/MainForm.resx
Original file line number Diff line number Diff line change
Expand Up @@ -150,28 +150,28 @@
<metadata name="toolTipForButton.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>339, 17</value>
</metadata>
<metadata name="clmnEnvironmentName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="clmnName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="clmnEnvironmentValue.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="clmnValue.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="clmnName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="dataGridColumnText.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="clmnValue.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="dataGridColumnText.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="clmnName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="clmnEnvironmentName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="clmnValue.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="clmnEnvironmentValue.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="dataGridColumnText.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="clmnEnvironmentName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="dataGridColumnText.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="clmnEnvironmentValue.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
Expand Down
Binary file added WindowTextExtractor/Libs/PresentationCore.dll
Binary file not shown.
Binary file not shown.
Binary file added WindowTextExtractor/Libs/Windows.WinMD
Binary file not shown.
22 changes: 9 additions & 13 deletions WindowTextExtractor/Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 28dfce3

Please sign in to comment.