WPF制作文字OCR软件(一):本地图片OCR识别
一、前言
上一篇文章,我使用python来进行文字OCR,但是python在图形化编程方面并不友好,所以我打算放弃使用python来搭建一款文字OCR软件。从这篇文章开始,我将分成几个部分来分享如何使用WPF(Windows Presentation Foundation
)利用百度智能云API制作一款文字OCR软件。
WPF(Windows Presentation Foundation)是微软推出的基于Windows 的用户界面框架,属于.NET Framework 3.0的一部分。它提供了统一的编程模型、语言和框架,真正做到了分离界面设计人员与开发人员的工作;同时它提供了全新的多媒体交互用户图形界面。(截自百度百科WPF)
首先需要说明的一点是,我并没有系统性地学过WPF甚至是C#语言,本人只不过有一些C++的基础,外加学过一点MFC而已,如果大家只是想要利用WPF做一个小应用,这些基础已经足够了。
本篇文章主要介绍如何使用WPF从本地图片上获取上面的文字。
二、编写程序
1.创建项目
进入Visual Studio(我使用的是vs2017)中新建工程,在其他语言中选择Visual C#再选择WPF应用
我使用的框架为.NET Framework 4.6.1
2.实现本地图片OCR功能
创建完工程后,进入MainWindow.xaml.cs中,定义两个变量clientId和clientSecret自己在百度智能云上创建的应用的API_KEY和SECRET_KEY;
之后添加以下代码:
/// <summary>
/// 获得accessToken
/// </summary>
/// <returns>AccessToken</returns>
public static String getAccessToken()
{
String authHost = "https://aip.baidubce.com/oauth/2.0/token";
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
List<KeyValuePair<String, String>> paraList = new List<KeyValuePair<string, string>>();
paraList.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
paraList.Add(new KeyValuePair<string, string>("client_id", clientId));
paraList.Add(new KeyValuePair<string, string>("client_secret", clientSecret));
try
{
System.Net.Http.HttpResponseMessage response = client.PostAsync(authHost, new System.Net.Http.FormUrlEncodedContent(paraList)).Result;
String result = response.Content.ReadAsStringAsync().Result;
String[] SpiltStr1 = result.Split(',');
String[] SpiltStr2 = SpiltStr1[3].Split(':');
String[] SpiltStr3 = SpiltStr2[1].Split('"');
return SpiltStr3[1];
}
catch
{
System.Windows.MessageBox.Show("出错了,请检查网络之后重试");
return null;
}
}
/// <summary>
/// 上传图片,获得识别内容
/// </summary>
/// <returns></returns>
private string GetWords(string path)
{
DateTime startTime = DateTime.Now;
string token = getAccessToken();
string host = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=" + token;
Encoding encoding = Encoding.Default;
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(host);
request.Method = "post";
request.KeepAlive = true;
// 图片的base64编码
string base64 = getFileBase64(path);
String str = "image=" + HttpUtility.UrlEncode(base64);
byte[] buffer = encoding.GetBytes(str);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string result = reader.ReadToEnd();
return result;
}
/// <summary>
/// 转换为用 Base64 数字编码的字符串表示形式
/// </summary>
/// <param name="fileName">文件路径</param>
/// <returns>字符串</returns>
public static String getFileBase64(String fileName)
{
FileStream filestream = new FileStream(fileName, FileMode.Open);
byte[] arr = new byte[filestream.Length];
filestream.Read(arr, 0, (int)filestream.Length);
string baser64 = Convert.ToBase64String(arr);
filestream.Close();
return baser64;
}
上面说过官方的程序存在BUG,因为官方给出的获取Access Token的程序有一点问题。如果只是使用官方程序,会返回如下错误,可以看出是Access token的问题。
通过Debug可以发现在getAccessToken()
函数中返回的不仅仅有Access token,还有其他值,所以需要进行一点处理,对字符串进行分割。处理的程序如下:
String[] SpiltStr1 = result.Split(',');
String[] SpiltStr2 = SpiltStr1[3].Split(':');
String[] SpiltStr3 = SpiltStr2[1].Split('"');
return SpiltStr3[1];
需要注意在使用上面的程序时,需要添加如下引用
using System.IO;
using System.Net;
using System.Web;
其中 System.Web可能需要从引用中添加,而不只是单单写在程序中
我们在项目下面新建一个文件夹,然后将一张图片放在该文件夹内,如图:
在mainwindow函数中添加如下程序:
public MainWindow()
{
InitializeComponent();
string str=GetWords("D:\\VS2017Project\\OCRCSDN\\OCRCSDN\\resources\\wpf.png");
MessageBox.Show(str);
}
消息框返回的信息为:
很显然,这并不是我们所需要的信息,所以接下来要对返回的信息进行处理。通过观察,我们可以发现返回的信息符合json的格式,所以可以将字符串json化之后进行处理。
3.字符串JSON化处理
首先点击项目-->管理Nuget程序包
,搜索json,选择第一个Newtonsoft.Json安装。
安装好后,在mainwindow.xaml.cs中添加以下程序:
public String Str2Json(string text)
{
JObject jo = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(text);
string str = "";
for (int i = 0; i < jo["words_result"].Count(); i++)
{
str += jo["words_result"][i]["words"].ToString() + '\n';
}
return str;
}
需要添加 using Newtonsoft.Json.Linq;
将MainWindow()函数的程序修改如下:
public MainWindow()
{
InitializeComponent();
string str=GetWords("D:\\VS2017Project\\OCRCSDN\\OCRCSDN\\resources\\wpf.png");
string info = Str2Json(str);
MessageBox.Show(info);
}
返回的结果如图:
三、结语
本篇文章到这里就结束了,因为wpf默认的窗口并不好看,所以下一篇文章将主要介绍如何自定义WPF窗口。