mirror of
https://github.com/gnh1201/welsonjs.git
synced 2024-11-26 15:31:42 +00:00
Add the Bitmap Comparison with CRC32 hashing
This commit is contained in:
parent
12ce97c385
commit
0742f17f2a
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Hashing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -14,6 +15,7 @@ using System.Windows.Forms;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Tesseract;
|
using Tesseract;
|
||||||
using WelsonJS.Service;
|
using WelsonJS.Service;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
public class ScreenMatch
|
public class ScreenMatch
|
||||||
{
|
{
|
||||||
|
@ -114,12 +116,12 @@ public class ScreenMatch
|
||||||
private List<string> _params = new List<string>();
|
private List<string> _params = new List<string>();
|
||||||
private bool isSearchFromEnd = false;
|
private bool isSearchFromEnd = false;
|
||||||
private bool isSaveToFile = false;
|
private bool isSaveToFile = false;
|
||||||
private bool isUseSampleClipboard = false;
|
|
||||||
private bool isUseSampleOCR = false;
|
|
||||||
private Size sampleSize;
|
private Size sampleSize;
|
||||||
private int sampleAdjustX = 0;
|
private int sampleAdjustX;
|
||||||
private int sampleAdjustY = 0;
|
private int sampleAdjustY;
|
||||||
private List<string> sampleAny;
|
private List<string> sampleAny;
|
||||||
|
private List<string> sampleClipboard;
|
||||||
|
private List<string> sampleOcr;
|
||||||
private List<string> sampleNodup;
|
private List<string> sampleNodup;
|
||||||
private Size sampleNodupSize;
|
private Size sampleNodupSize;
|
||||||
private Queue<Bitmap> sampleOutdated;
|
private Queue<Bitmap> sampleOutdated;
|
||||||
|
@ -133,13 +135,20 @@ public class ScreenMatch
|
||||||
|
|
||||||
templateDirectoryPath = Path.Combine(workingDirectory, "app/assets/img/_templates");
|
templateDirectoryPath = Path.Combine(workingDirectory, "app/assets/img/_templates");
|
||||||
outputDirectoryPath = Path.Combine(workingDirectory, "app/assets/img/_captured");
|
outputDirectoryPath = Path.Combine(workingDirectory, "app/assets/img/_captured");
|
||||||
|
|
||||||
templateImages = new List<Bitmap>();
|
templateImages = new List<Bitmap>();
|
||||||
|
|
||||||
|
// Initialize variables for sampling process
|
||||||
sampleSize = new Size
|
sampleSize = new Size
|
||||||
{
|
{
|
||||||
Width = 128,
|
Width = 128,
|
||||||
Height = 128
|
Height = 128
|
||||||
};
|
};
|
||||||
|
sampleAdjustX = 0;
|
||||||
|
sampleAdjustY = 0;
|
||||||
|
sampleAny = new List<string>();
|
||||||
|
sampleClipboard = new List<string>();
|
||||||
|
sampleOcr = new List<string>();
|
||||||
|
sampleNodup = new List<string>();
|
||||||
sampleNodupSize = new Size
|
sampleNodupSize = new Size
|
||||||
{
|
{
|
||||||
Width = 128,
|
Width = 128,
|
||||||
|
@ -212,8 +221,7 @@ public class ScreenMatch
|
||||||
|
|
||||||
case "sample_clipboard":
|
case "sample_clipboard":
|
||||||
{
|
{
|
||||||
isUseSampleClipboard = true;
|
sampleClipboard = new List<string>(config_value.Split(':'));
|
||||||
this.parent.Log($"Use Clipboard within a {sampleSize.Width}x{sampleSize.Height} pixel range around specific coordinates.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,8 +229,7 @@ public class ScreenMatch
|
||||||
{
|
{
|
||||||
tesseractDataPath = Path.Combine(workingDirectory, "app/assets/tessdata_best");
|
tesseractDataPath = Path.Combine(workingDirectory, "app/assets/tessdata_best");
|
||||||
tesseractLanguage = "eng";
|
tesseractLanguage = "eng";
|
||||||
isUseSampleOCR = true;
|
sampleOcr = new List<string>(config_value.Split(':'));
|
||||||
this.parent.Log($"Use OCR within a {sampleSize.Width}x{sampleSize.Height} pixel range around specific coordinates.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +402,7 @@ public class ScreenMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Point> matchPositions = FindTemplate(_mainImage, (Bitmap)image.Clone());
|
List<Point> matchPositions = FindTemplate(_mainImage, (Bitmap)image.Clone());
|
||||||
matchPositions.ForEach((matchPosition) =>
|
foreach (Point matchPosition in matchPositions)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -409,12 +416,14 @@ public class ScreenMatch
|
||||||
Position = matchPosition,
|
Position = matchPosition,
|
||||||
Text = text
|
Text = text
|
||||||
});
|
});
|
||||||
|
|
||||||
|
break; // Only one
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
parent.Log($"Ignore the match. {ex.Message}");
|
parent.Log($"Ignore the match. {ex.Message}");
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.Count > 0)
|
if (results.Count > 0)
|
||||||
|
@ -431,7 +440,7 @@ public class ScreenMatch
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap cropBitmap(Bitmap bitmap, Point matchPosition, Size templateSize, Size sampleSize, int dx = 0, int dy = 0)
|
public Bitmap CropBitmap(Bitmap bitmap, Point matchPosition, Size templateSize, Size sampleSize, int dx = 0, int dy = 0)
|
||||||
{
|
{
|
||||||
// Adjust coordinates to the center
|
// Adjust coordinates to the center
|
||||||
int x = matchPosition.X + (templateSize.Width / 2);
|
int x = matchPosition.X + (templateSize.Width / 2);
|
||||||
|
@ -464,14 +473,15 @@ public class ScreenMatch
|
||||||
string text = "";
|
string text = "";
|
||||||
|
|
||||||
// Crop image
|
// Crop image
|
||||||
Bitmap croppedBitmap = cropBitmap(bitmap, matchPosition, templateSize, sampleSize, sampleAdjustX, sampleAdjustY);
|
Bitmap croppedBitmap = CropBitmap(bitmap, matchPosition, templateSize, sampleSize, sampleAdjustX, sampleAdjustY);
|
||||||
|
|
||||||
// Save to the outdated samples
|
// Save to the outdated samples
|
||||||
if (sampleNodup.Contains(templateName))
|
if (sampleNodup.Contains(templateName))
|
||||||
{
|
{
|
||||||
Bitmap croppedNodupBitmap = cropBitmap(bitmap, matchPosition, templateSize, sampleNodupSize);
|
Bitmap croppedNodupBitmap = CropBitmap(bitmap, matchPosition, templateSize, sampleNodupSize);
|
||||||
int bitmapHash = croppedNodupBitmap.GetHashCode();
|
uint bitmapCrc32 = ComputeBitmapCrc32(croppedNodupBitmap);
|
||||||
bool bitmapExists = sampleOutdated.Any(x => x.GetHashCode() == bitmapHash);
|
parent.Log($"bitmapCrc32: {bitmapCrc32}");
|
||||||
|
bool bitmapExists = sampleOutdated.Any(x => ComputeBitmapCrc32(x) == bitmapCrc32);
|
||||||
if (bitmapExists)
|
if (bitmapExists)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"This may be a duplicate request. {templateName}");
|
throw new InvalidOperationException($"This may be a duplicate request. {templateName}");
|
||||||
|
@ -484,7 +494,7 @@ public class ScreenMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
// if use Clipboard
|
// if use Clipboard
|
||||||
if (isUseSampleClipboard)
|
if (sampleClipboard.Contains(templateName))
|
||||||
{
|
{
|
||||||
Thread th = new Thread(new ThreadStart(() =>
|
Thread th = new Thread(new ThreadStart(() =>
|
||||||
{
|
{
|
||||||
|
@ -503,7 +513,7 @@ public class ScreenMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
// if use OCR
|
// if use OCR
|
||||||
if (isUseSampleOCR)
|
if (sampleOcr.Contains(templateName))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -755,4 +765,18 @@ public class ScreenMatch
|
||||||
|
|
||||||
return binaryImage;
|
return binaryImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private uint ComputeBitmapCrc32(Bitmap bitmap)
|
||||||
|
{
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
|
||||||
|
|
||||||
|
byte[] bitmapBytes = ms.ToArray();
|
||||||
|
Crc32 crc32 = new Crc32();
|
||||||
|
crc32.Append(bitmapBytes);
|
||||||
|
|
||||||
|
return BitConverter.ToUInt32(crc32.GetCurrentHash(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -142,6 +142,9 @@
|
||||||
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.8.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.8.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.IO.Hashing, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\System.IO.Hashing.8.0.0\lib\net462\System.IO.Hashing.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Management" />
|
<Reference Include="System.Management" />
|
||||||
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<package id="RestSharp" version="112.0.0" targetFramework="net48" />
|
<package id="RestSharp" version="112.0.0" targetFramework="net48" />
|
||||||
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
||||||
<package id="System.Diagnostics.DiagnosticSource" version="8.0.1" targetFramework="net48" />
|
<package id="System.Diagnostics.DiagnosticSource" version="8.0.1" targetFramework="net48" />
|
||||||
|
<package id="System.IO.Hashing" version="8.0.0" targetFramework="net48" />
|
||||||
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
|
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
|
||||||
<package id="System.Net.Http.WinHttpHandler" version="8.0.2" targetFramework="net48" />
|
<package id="System.Net.Http.WinHttpHandler" version="8.0.2" targetFramework="net48" />
|
||||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
|
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
|
||||||
|
|
|
@ -13,7 +13,7 @@ DISABLE_SCREEN_TIME=true
|
||||||
DISABLE_FILE_MONITOR=true
|
DISABLE_FILE_MONITOR=true
|
||||||
; window or screen
|
; window or screen
|
||||||
SCREEN_TIME_MODE=screen
|
SCREEN_TIME_MODE=screen
|
||||||
; backward,save,sample_ocr,sample_clipboard,sample_width=128,sample_height=128,sample_adjust_x=0,sample_adjust_y=0,sample_only=button.png:message.png,sample_nodup=message.png,process_name=notepad.exe
|
; backward,save,sample_width=128,sample_height=128,sample_adjust_x=0,sample_adjust_y=0,sample_any=button.png:message.png:like.png,sample_ocr=like.png,sample_clipboard=button.png,sample_nodup=message.png,process_name=notepad.exe
|
||||||
SCREEN_TIME_PARAMS=
|
SCREEN_TIME_PARAMS=
|
||||||
; default: http://localhost:50051
|
; default: http://localhost:50051
|
||||||
GRPC_HOST=http://localhost:50051
|
GRPC_HOST=http://localhost:50051
|
||||||
|
|
Loading…
Reference in New Issue
Block a user