今天是 g0v 黑客松,當初沒有報名,只好在家裡看看能做些什麼。
然後看到了有一個主題是要把政治獻金人肉轉回電子檔,有聽到 ronny 在 ODBC 上面提到就很想做做看。
我在
g0v 做的政治獻金網站翻譯了三個多小時,小有心得,有一些想法,希望能實做看看。
- 翻譯時順便用 OCR 先掃一遍,如果運氣好辨識出來,那 user 就不用再打字了。
- 看了一下原始表格,其實會有很大量的重複詞彙,其實可以先整理起來。
去找了一下有沒有甚麼 OCR 的函式庫。發現常用的有
- tesseract-ocr
- Office內建的 OCR: Microsot Office Document Imaging Library
我現在熟的是 PHP 還有 C# (好衝突)。
但又想要快速開發,然後我現在沒有 WebServer,於是就決定用 C# 和 MODI 希望能把研究的時間花到最少。
在開發中這次學到的技巧:
- C# 串 JSON
- C# 串 WebService
- C# 串 MODI
先放完成圖: [
原始碼]
C# 串 JSON + WebService
要增加 Reference
- System.ServiceModel.Web
- System.Runtime.Serialization
範例
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
[DataContract]
class GetRandomResponse
{
[DataMember(Name = "img_url")]
public string ImageUrl { get; set; }
[DataMember(Name = "page")]
public int Page { get; set; }
[DataMember(Name = "x")]
public int x { get; set; }
[DataMember(Name = "y")]
public int y { get; set; }
[DataMember(Name = "ans")]
public string Answer { get; set; }
}
public GetRandomResponse GetRandom()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(API_GETRANDOM);
GetRandomResponse resp = null;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(GetRandomResponse));
resp = serializer.ReadObject(response.GetResponseStream()) as GetRandomResponse;
}
return resp;
}
public string PostFillCell(int page, int x, int y, string ans)
{
this.CleanLog();
string uri = string.Format("{0}/{1}/{2}/{3}", API_POSTANSWER, page, x, y);
this.AppendLog("URL=" + uri);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string param = "ans=" + HttpUtility.UrlEncode(ans);
byte[] bs = Encoding.ASCII.GetBytes(param);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
string result;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
StreamReader sr = new StreamReader(response.GetResponseStream());
result = sr.ReadToEnd();
sr.Close();
}
return result;
}
C# 串 MODI
要增加 Reference
辨識的程式碼範例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Drawing;
namespace OCR
{
class OCREngine
{
public static string DoOCR(Bitmap bmp, MODI.MiLANGUAGES lang = MODI.MiLANGUAGES.miLANG_ENGLISH)
{
string str = string.Empty;
string tmpfile = Path.GetTempFileName() + ".png";
bmp.Save(tmpfile, System.Drawing.Imaging.ImageFormat.Png);
try
{
MODI.Document mdoc = new MODI.Document();
mdoc.Create(tmpfile);
MODI.Image mImage = (MODI.Image)mdoc.Images[0];
mImage.OCR(lang, true, true);
foreach (MODI.Word word in mImage.Layout.Words)
{
str += word.Text;
}
mdoc.Close();
}
catch { }
finally
{
File.Delete(tmpfile);
}
return str;
}
}
}