一款文字識別小工具的開發
操作方式
截圖的實現
在獨立線程進行OCR識別,避免UI卡死
配置文件讀取和日誌記錄
使用.gitignore時遇到的問題
給媳婦做的一款文字識別小工具,調用了百度雲OCR介面,穩定、快速,比現在用的方便多了。百度雲的高精度版OCR介面最多支持每天500次免費調用。
源碼:https://github.com/zhixin9001/OCR_Tool
一、操作方式
左鍵按下選擇識別區域,右鍵退回主界面,左鍵雙擊開始文字識別
二、截圖的實現
截圖功能使用了https://www.cnblogs.com/zhiboday/p/6024427.html這裡提供的代碼。
關鍵在於使用winform的雙緩存機制防止閃爍:
privatevoidCapture_Load(objectsender, EventArgs e)
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint,true);
this.UpdateStyles();
this.Cursor = Cursors.Cross;
this.originBmp =newBitmap(this.BackgroundImage);
}
privatevoidCapture_MouseMove(objectsender, MouseEventArgs e)
{
// 確保截圖開始
if(CatchStart)
{
// 新建一個圖片對象,讓它與屏幕圖片相同
Bitmap copyBmp = (Bitmap)originBmp.Clone();
// 獲取滑鼠按下的坐標
Point newPoint =newPoint(DownPoint.X, DownPoint.Y);
// 新建畫板和畫筆
Graphics g = Graphics.FromImage(copyBmp);
Pen p =newPen(Color.Red, 1);
// 獲取矩形的長寬
intwidth = Math.Abs(e.X - DownPoint.X);
intheight = Math.Abs(e.Y - DownPoint.Y);
if(e.X
{
newPoint.X = e.X;
}
if(e.Y
{
newPoint.Y = e.Y;
}
CatchRectangle =newRectangle(newPoint,newSize(width, height));
// 將矩形畫在畫板上
g.DrawRectangle(p, CatchRectangle);
// 釋放目前的畫板
g.Dispose();
p.Dispose();
// 從當前窗體創建新的畫板
Graphics g1 =this.CreateGraphics();
// 將剛才所畫的圖片畫到截圖窗體上
// 為什麼不直接在當前窗體畫圖呢?
// 如果自己解決將矩形畫在窗體上,會造成圖片抖動並且有無數個矩形
// 這樣實現也屬於二次緩衝技術
g1.DrawImage(copyBmp,newPoint(0, 0));
g1.Dispose();
// 釋放拷貝圖片,防止內存被大量消耗
copyBmp.Dispose();
}
}
三、在獨立線程進行OCR識別,避免UI卡死
為了避免在OCR識別時界面卡死,需要在UI線程之外創建獨立的線程,識別完成後再使用委託的方式更新在UI線程中的RichTextBox。
privatevoidCapture_captureFinished(objectsender, EventArgs e)
{
Thread objThread =newThread(newThreadStart(delegate
{
ThreadMethodTxt(formCapture.base64Image);
}));
objThread.Start();
}
//創建一個用於操作richtextbox的委託
publicdelegatevoidocrDelegete(byte[] base64Img);
publicvoidThreadMethodTxt(byte[] base64Img)
{
varocrDelMethod =newocrDelegete(OcrMethod);
this.BeginInvoke(ocrDelMethod, base64Img);
}
privatevoidOcrMethod(byte[] base64Img)
{
try
{
varapiAuthConfig = Api_Auth.apiAuthConfig;
varclient =newBaidu.Aip.Ocr.Ocr(apiAuthConfig.API_KEY, apiAuthConfig.SECRET_KEY);
varresult = client.AccurateBasic(base64Img);
varlast = result.Last.Last();
this.rtbResult.ResetText();
for(vari = 0; i
{
varstr = JsonConvert.DeserializeObject(last[i].ToString());
this.rtbResult.AppendText(str.words);
this.rtbResult.AppendText("
");
}
}
catch(Exception e)
{
LogHelper.WriteLog(e);
}
finally
{
this.Show();
formCapture.Close();
}
}
四、配置文件讀取和日誌記錄
Api_Auth.json中配置了調用OCR介面需要的KEY和密鑰,這需要到百度雲申請:
Json文件中不能直接添加註釋,為此可以添加「_comment」節點,解析時會忽略這個節點,讀取配置的代碼:
classApi_Auth_Model
{
publicstringAPI_KEY;
publicstringSECRET_KEY;
}
staticclassApi_Auth
{
publicstaticApi_Auth_Model apiAuthConfig=GetJsonConfig();
publicstaticApi_Auth_Model GetJsonConfig()
{
vardataDir = AppDomain.CurrentDomain.BaseDirectory;
varfullpath = dataDir +"Configs//Api_Auth.json";
using(varreader =newStreamReader(fullpath))
{
varcontent = reader.ReadToEnd();
varobj = JsonConvert.DeserializeObject(content);
returnobj;
}
}
}
調用OCR介面時可能會遇到授權失敗、調用次數超限等問題,所以增加日誌記錄:
classLogHelper
{
publicconststringLOG_DIR ="Logs";
publicconststringLOG_SUFFIX ="log";
publicstaticvoidWriteLog(Exception e)
{
vardataDir = AppDomain.CurrentDomain.BaseDirectory;
if(!Directory.Exists(Path.Combine(dataDir, LogHelper.LOG_DIR)))
{
Directory.CreateDirectory(Path.Combine(dataDir, LogHelper.LOG_DIR));
}
varcurrentMonthLogPath = Path.Combine(dataDir, LogHelper.LOG_DIR, LogHelper.GetCurrentMonthString());
varcurrentMonthLogFile = currentMonthLogPath +"."+ LogHelper.LOG_SUFFIX;
if(!File.Exists(currentMonthLogPath +"."+ LogHelper.LOG_SUFFIX))
{
using(varwriter = File.Create(currentMonthLogFile)) { }
}
using(varwriter = File.AppendText(currentMonthLogFile))
{
writer.WriteLine(LogHelper.GetExceptionString(e));
}
}
五、使用.gitignore時遇到的問題
之前不小心把不需要提交的內容也簽入了,後來發現配置gitignore沒生效,這是因為已經提交過的內容,就算再為其添加ignore也無濟於事,這時可以執行git rm [filepath] --cached。
TAG:菜鳥程序員成長記 |