- A+
所属分类:.NET技术
1. 简单需求
通过图文识别读取一个指定window窗口的文本。 获取窗口句柄,截图保存成bitmap ,调用图文识别库.
测试结果是对中文下的识别不是特别好。
需要注意的是,tessdata要下载指定目录页下。
2. 引用包
a. 引用 tesseract4.1 b. Emgu.CV组件
3. 上代码
using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; using Emgu.CV; using Emgu.CV.OCR; using Emgu.CV.Structure; using Tesseract; using System.Windows.Forms; using Pix = Tesseract.Pix; using PageSegMode = Tesseract.PageSegMode; public class Program { [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] public static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); [DllImport("gdi32.dll")] public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos); [DllImport("user32.dll", SetLastError = true)] public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo); private const int KEYEVENTF_EXTENDEDKEY = 0x0001; private const int KEYEVENTF_KEYUP = 0x0002; private const int VK_MENU = 0x12; // Alt private const int VK_S = 0x53; // S key public static Bitmap CaptureWindow(IntPtr hWnd) { RECT rect; GetWindowRect(hWnd, out rect); Bitmap bmp = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(bmp); g.CopyFromScreen(rect.Left, rect.Top, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy); return bmp; } public static void Main() { string windowTitle = "*无标题 - 记事本"; //*无标题 - 记事本 IntPtr hWnd = FindWindow(null, windowTitle); if (hWnd == IntPtr.Zero) { Console.WriteLine($"Could not find window with title '{windowTitle}'"); return; } SetForegroundWindow(hWnd); //SendKeys.SendWait("%(s)"); //发送Alt+S事件 // Press Alt + S //keybd_event(VK_MENU, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0); //keybd_event(VK_S, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0); //// Release Alt + S //keybd_event(VK_S, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); //keybd_event(VK_MENU, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); //图文识别 Bitmap bmp = CaptureWindow(hWnd); //tessdata/tessdata-4.1.0 TesseractEngine engine = new TesseractEngine(@"./tessdata", "eng", EngineMode.TesseractAndLstm); using (Bitmap bmpImage = new Bitmap(bmp)) { byte[] imageData = ImageToByte(bmpImage); using (var image = Pix.LoadFromMemory(imageData)) { using (var page = engine.Process(image)) { var text = page.GetText(); Console.WriteLine("Text recognized from image: {0}", text); } } } } private static byte[] ImageToByte(Bitmap img) { ImageConverter converter = new ImageConverter(); return (byte[])converter.ConvertTo(img, typeof(byte[])); } }
上述代码使用的是net6.0 开发的。控制台程序模拟windows事件,尤其是键盘快捷键时,有点问题。暂未处理。
就这样吧,兴趣所致,就是玩玩。 天太冷了,不想写的太多。 纯粹凑字数。