【先上一張效果圖】:算法
1、原理:瀏覽器
其實原理很簡單:this
1.手機投屏到電腦;spa
2.截取投屏畫面的題目部分,進行識別,獲得題目和三個答案;code
3.將答案按照必定的算法,進行搜索,得出推薦答案;對象
4.添加了一些其餘輔助功能,好比:瀏覽器搜索結果展現、關鍵字高亮、瀏覽器可點擊等;blog
2、二營長,把個人意大利...............代碼,呈上來,給友軍看看事件
1.手機投屏:圖片
方式不少,這裏只列舉幾個比較經常使用、且本身感受簡單易用的:內存
A.IOS:局域網內,能夠利用iTools裏的蘋果錄屏大師(airplay),進行投屏;
B.安卓:利用鏈接線,能夠用Totall Control,將安卓手機的畫面投到電腦上;並且電腦上還能直接操做手機;
C.模擬器:通常都是安卓模擬器;能夠自行下載並安裝;
2.截取畫面中的題目和答案
A.先設置要截圖的區域。
我建立了一個窗體,專門用於設置截圖區域,給它取名叫:frmCutter。
原理:在主窗體打開frmCutter時,就將frmCutter全拼顯示。同時截取一張整個屏幕的圖片,把它設置成frmCutter窗體的背景圖片。
這樣就能在frmCutter上自由地設置了。
主窗體打開frmCutter窗體時:
1 // 新建一個和屏幕大小相同的圖片 2 Bitmap catchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height); 3 4 // 建立一個畫板,讓咱們能夠在畫板上畫圖 5 // 這個畫板也就是和屏幕大小同樣大的圖片 6 // 咱們能夠經過Graphics這個類在這個空白圖片上畫圖 7 Graphics g = Graphics.FromImage(catchBmp); 8 9 // 把屏幕圖片拷貝到咱們建立的空白圖片 catchBmp中 10 g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height)); 11 12 // 建立截圖窗體 13 frmCutter _frmCutter = new frmCutter(); 14 _frmCutter.Tag = this; 15 16 // 指示窗體的背景圖片爲屏幕圖片 17 _frmCutter.BackgroundImage = catchBmp; 18 19 _frmCutter.Width = Screen.AllScreens[0].Bounds.Width; 20 _frmCutter.Height = Screen.AllScreens[0].Bounds.Height; 21 DialogResult dr = _frmCutter.ShowDialog();
而後再frmCutter窗體中,寫入幾個事件:
1 //點擊鼠標右鍵時,取消設置 2 private void frmCutter_MouseClick(object sender, MouseEventArgs e) 3 { 4 if (e.Button == MouseButtons.Right) 5 { 6 this.DialogResult = DialogResult.OK; 7 this.Close(); 8 } 9 } 10 11 //點擊鼠標左鍵時,開始畫區域圖 12 private void frmCutter_MouseDown(object sender, MouseEventArgs e) 13 { 14 // 鼠標左鍵按下是開始畫圖,也就是截圖 15 if (e.Button == MouseButtons.Left) 16 { 17 // 若是捕捉沒有開始 18 if (!_catchStart && !_catchFinished) 19 { 20 _catchStart = true; 21 22 // 保存此時鼠標按下座標 23 Point newPoint = new Point(e.X, e.Y); 24 25 _downPoint = newPoint; 26 27 Tools.StartPoint = newPoint; 28 } 29 } 30 } 31 32 //鼠標移動時,根據移動的鼠標和點擊時的第一個點,繪製矩形 33 private void frmCutter_MouseMove(object sender, MouseEventArgs e) 34 { 35 #region 確保截圖開始 36 if (_catchStart && !_catchFinished) 37 { 38 // 新建一個圖片對象,讓它與屏幕圖片相同 39 Bitmap copyBmp = (Bitmap)Tools.ScreenShots.Clone(); 40 41 // 獲取鼠標按下的座標 42 Point newPoint = new Point(_downPoint.X, _downPoint.Y); 43 44 // 新建畫板和畫筆 45 Graphics g = Graphics.FromImage(copyBmp); 46 Pen p = new Pen(Color.Red, 1); 47 48 // 獲取矩形的長寬 49 int width = Math.Abs(e.X - _downPoint.X); 50 int height = Math.Abs(e.Y - _downPoint.Y); 51 if (e.X < _downPoint.X) 52 { 53 newPoint.X = e.X; 54 } 55 if (e.Y < _downPoint.Y) 56 { 57 newPoint.Y = e.Y; 58 } 59 60 _catchRectangle = new Rectangle(newPoint, new Size(width, height)); 61 62 Tools.CatchRectangle = new Rectangle(newPoint, new Size(width, height)); 63 Tools.CatchRectangleSize = new Size(width, height); 64 65 66 // 將矩形畫在畫板上 67 g.DrawRectangle(p, _catchRectangle); 68 69 // 釋放目前的畫板 70 g.Dispose(); 71 p.Dispose(); 72 // 從當前窗體建立新的畫板 73 Graphics g1 = this.CreateGraphics(); 74 75 // 將剛纔所畫的圖片畫到截圖窗體上 76 // 爲何不直接在當前窗體畫圖呢? 77 // 若是本身解決將矩形畫在窗體上,會形成圖片抖動而且有無數個矩形 78 // 這樣實現也屬於二次緩衝技術 79 g1.DrawImage(copyBmp, new Point(0, 0)); 80 g1.Dispose(); 81 // 釋放拷貝圖片,防止內存被大量消耗 82 copyBmp.Dispose(); 83 } 84 #endregion 85 } 86 87 //鼠標點擊後,彈起來時,完成矩形的繪製 88 private void frmCutter_MouseUp(object sender, MouseEventArgs e) 89 { 90 if (e.Button == MouseButtons.Left) 91 { 92 // 若是截圖已經開始,鼠標左鍵彈起設置截圖完成 93 if (_catchStart) 94 { 95 Tools.EndPoint = new Point(e.X, e.Y); 96 97 _catchStart = false; 98 _catchFinished = true; 99 } 100 } 101 } 102 103 //雙擊,肯定當前選擇的設置 104 private void frmCutter_MouseDoubleClick(object sender, MouseEventArgs e) 105 { 106 if (e.Button == MouseButtons.Left && _catchFinished) 107 { 108 if (this.Tag != null) 109 { 110 frmMain _frmMain = (frmMain)this.Tag; 111 if (_frmMain != null) 112 { 113 //_frmMain.btnRead.Focus(); 114 _frmMain.ReadImageResult(); 115 } 116 } 117 118 this.DialogResult = DialogResult.OK; 119 this.Close(); 120 } 121 }
B.設置好截圖區域後,每次題目出現時,變對該區域截圖:
1 //截取設置的區域屏幕圖片 2 Bitmap _screenShots = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height); 3 // 建立一個畫板,讓咱們能夠在畫板上畫圖 4 // 這個畫板也就是和屏幕大小同樣大的圖片 5 // 咱們能夠經過Graphics這個類在這個空白圖片上畫圖 6 Graphics g_screenShots = Graphics.FromImage(_screenShots); 7 // 把屏幕圖片拷貝到咱們建立的空白圖片 CatchBmp中 8 g_screenShots.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width,
Screen.AllScreens[0].Bounds.Height)); 9 10 //剪切的圖片 11 _catchBmp = new Bitmap(Tools.CatchRectangleSize.Width, Tools.CatchRectangleSize.Height); 12 Graphics g = Graphics.FromImage(_catchBmp); 13 g.DrawImage(_screenShots, new Rectangle(0, 0, Tools.CatchRectangleSize.Width, Tools.CatchRectangleSize.Height),
Tools.CatchRectangle, GraphicsUnit.Pixel); 14 g.Dispose(); 15 g_screenShots.Dispose(); 16 17 //顯示圖像 18 this.imgCut.BackgroundImage = (Image)_catchBmp;
C.將截到的問題和答案圖片,用OCR識別
好比,我如今設置並截取到了這張圖片:
識別圖片中的文字,OCR軟件和API也很多。之前我用的谷歌tesseract4.0,安裝在本機的,沒作詞庫,識別率通常。
後來發現百度OCR天天免費調用500次,果斷轉場!事實證實,正確率仍是高不少。
D.獲得識別結果,將識別結果處理後,進行百度搜索:
建立了一個試題實體,後面用起來就方便了:
1 /// <summary> 2 /// 試題類 3 /// </summary> 4 public class QuestionModel 5 { 6 /// <summary> 7 /// 問題 8 /// </summary> 9 public string Question { get; set; } 10 11 /// <summary> 12 /// 答案1 13 /// </summary> 14 public string Answer1 { get; set; } 15 16 /// <summary> 17 /// 答案2 18 /// </summary> 19 public string Answer2 { get; set; } 20 21 /// <summary> 22 /// 答案3 23 /// </summary> 24 public string Answer3 { get; set; } 25 }
E.百度搜索,並顯示參考答案:
a).算法搜索:
1.用題目去百度搜索。在搜索的結果中,查詢答案出現的次數。
2.用題目+答案去搜索。獲得每一個組合的百度結果個數。
而後將上述兩種方法,根據權重權衡,用戶能夠自行決定偏向於哪一種結果。
b).輔助搜索:
右邊還放了一個瀏覽器,能夠在獲得識別結果的第一時間,呈現出根據題目搜索百度的結果;而且在裏面高亮顯示3個答案關鍵字。
3、坐等吃雞!
自動截圖、自動識別、自動搜索、自動給出參考答案、自動展示出搜索頁面並高亮顯示關鍵字……
多了一系列的輔助功能,想不吃雞都難啊~
(PS:熱烈歡迎廣大道友一塊兒交流、指點,你們一塊兒更上一層樓!)
2018.01.25.
下面給你們推薦兩個小福利: