Update the screen time feature on WelsonJS.Service

This commit is contained in:
Namhyeon Go 2024-08-02 16:51:49 +09:00
parent 70bce6eb72
commit 8df6270287
4 changed files with 67 additions and 54 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using WelsonJS.Service; using WelsonJS.Service;
@ -48,11 +49,15 @@ public class ScreenMatching
public int Bottom; public int Bottom;
} }
ServiceMain parent;
public List<Bitmap> templateImages; public List<Bitmap> templateImages;
string templateFolderPath; string templateFolderPath;
int currentTemplateIndex = 0;
public ScreenMatching(string workingDirectory) public ScreenMatching(ServiceBase _parent, string workingDirectory)
{ {
parent = (ServiceMain)_parent;
templateFolderPath = Path.Combine(workingDirectory, "app/assets/img/_templates"); templateFolderPath = Path.Combine(workingDirectory, "app/assets/img/_templates");
templateImages = new List<Bitmap>(); templateImages = new List<Bitmap>();
LoadTemplateImages(); LoadTemplateImages();
@ -80,20 +85,21 @@ public class ScreenMatching
Screen screen = Screen.AllScreens[i]; Screen screen = Screen.AllScreens[i];
Bitmap mainImage = CaptureScreen(screen); Bitmap mainImage = CaptureScreen(screen);
foreach (Bitmap templateImage in templateImages) Bitmap image = templateImages[currentTemplateIndex];
{ parent.Log($"Matching template {image.Tag as string} on the screen {i}...");
Point matchLocation = FindTemplate(mainImage, (Bitmap)templateImage.Clone(), out double maxCorrelation);
results.Add(new ScreenMatchResult Point matchLocation = FindTemplate(mainImage, (Bitmap)image.Clone(), out double maxCorrelation);
{ results.Add(new ScreenMatchResult
FileName = templateImage.Tag.ToString(), {
ScreenNumber = i, FileName = image.Tag.ToString(),
Location = matchLocation, ScreenNumber = i,
MaxCorrelation = maxCorrelation Location = matchLocation,
}); MaxCorrelation = maxCorrelation
} });
} }
currentTemplateIndex = ++currentTemplateIndex % templateImages.Count;
return results; return results;
} }
@ -126,21 +132,19 @@ public class ScreenMatching
Bitmap windowImage = CaptureWindow(hWnd); Bitmap windowImage = CaptureWindow(hWnd);
if (windowImage != null) if (windowImage != null)
{ {
foreach (var templateImage in templateImages) Bitmap image = templateImages[currentTemplateIndex];
{ Point matchLocation = FindTemplate(windowImage, image, out double maxCorrelation);
Point matchLocation = FindTemplate(windowImage, templateImage, out double maxCorrelation); string templateFileName = image.Tag as string;
string templateFileName = templateImage.Tag as string;
var result = new ScreenMatchResult var result = new ScreenMatchResult
{ {
FileName = templateFileName, FileName = templateFileName,
WindowHandle = hWnd, WindowHandle = hWnd,
WindowTitle = windowTitle, WindowTitle = windowTitle,
Location = matchLocation, Location = matchLocation,
MaxCorrelation = maxCorrelation MaxCorrelation = maxCorrelation
}; };
results.Add(result); results.Add(result);
}
} }
} }
catch { } catch { }
@ -148,6 +152,8 @@ public class ScreenMatching
return true; return true;
}, IntPtr.Zero); }, IntPtr.Zero);
currentTemplateIndex = ++currentTemplateIndex % templateImages.Count;
return results; return results;
} }
@ -194,10 +200,10 @@ public class ScreenMatching
{ {
for (int y = 0; y <= mainHeight - templateHeight; y++) for (int y = 0; y <= mainHeight - templateHeight; y++)
{ {
if (IsTemplateMatch(mainImage, templateImage, x, y)) if (IsTemplateMatch(mainImage, templateImage, x, y, 0.8)) // matched 80% or above
{ {
bestMatch = new Point(x, y); bestMatch = new Point(x, y);
maxCorrelation = 1; // 완전 일치 maxCorrelation = 1;
return bestMatch; return bestMatch;
} }
} }
@ -206,22 +212,29 @@ public class ScreenMatching
return bestMatch; return bestMatch;
} }
private bool IsTemplateMatch(Bitmap mainImage, Bitmap templateImage, int offsetX, int offsetY) private bool IsTemplateMatch(Bitmap mainImage, Bitmap templateImage, int offsetX, int offsetY, double threshold = 1.0)
{ {
int templateWidth = templateImage.Width; int templateWidth = templateImage.Width;
int templateHeight = templateImage.Height; int templateHeight = templateImage.Height;
int totalPixels = templateWidth * templateHeight;
int requiredMatches = (int)(totalPixels * threshold);
int matchedCount = 0;
Random rand = new Random();
for (int x = 0; x < templateWidth; x++) while (matchedCount < requiredMatches)
{ {
for (int y = 0; y < templateHeight; y++) int x = rand.Next(templateWidth);
int y = rand.Next(templateHeight);
Point point = new Point(x, y);
if (mainImage.GetPixel(x + offsetX, y + offsetY) != templateImage.GetPixel(x, y))
{ {
if (mainImage.GetPixel(x + offsetX, y + offsetY) != templateImage.GetPixel(x, y)) return false;
{
return false;
}
} }
matchedCount++;
} }
return true; return true;
} }
} }

View File

@ -31,6 +31,7 @@ using System.Runtime.InteropServices;
using MSScriptControl; using MSScriptControl;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace WelsonJS.Service namespace WelsonJS.Service
{ {
@ -204,11 +205,11 @@ namespace WelsonJS.Service
// set screen timer // set screen timer
if (!disabledScreenTime) if (!disabledScreenTime)
{ {
screenMatcher = new ScreenMatching(workingDirectory); screenMatcher = new ScreenMatching(this, workingDirectory);
Timer screenTimer = new Timer Timer screenTimer = new Timer
{ {
Interval = 10000 // 10 seconds Interval = 5000 // 5 seconds
}; };
screenTimer.Elapsed += OnScreenTime; screenTimer.Elapsed += OnScreenTime;
timers.Add(screenTimer); timers.Add(screenTimer);
@ -287,22 +288,6 @@ namespace WelsonJS.Service
return "void"; return "void";
} }
private void Log(string message)
{
string _message = $"{DateTime.Now}: {message}";
if (Environment.UserInteractive)
{
Console.WriteLine(_message);
}
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
writer.WriteLine(_message);
}
}
private Dictionary<string, string> ParseArguments(string[] args) private Dictionary<string, string> ParseArguments(string[] args)
{ {
var arguments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); var arguments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
@ -328,5 +313,20 @@ namespace WelsonJS.Service
return arguments; return arguments;
} }
public void Log(string message)
{
string _message = $"{DateTime.Now}: {message}";
if (Environment.UserInteractive)
{
Console.WriteLine(_message);
}
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
writer.WriteLine(_message);
}
}
} }
} }

Binary file not shown.

Binary file not shown.