篇一:WPF常用知識以及本項目設計總結:http://www.cnblogs.com/baiboy/p/wpf.html
篇二:基于OneNote難點突破和批量識别:http://www.cnblogs.com/baiboy/p/wpf1.html
篇三:批量處理後的txt檔案入庫處理:http://www.cnblogs.com/baiboy/p/wpf2.html
篇四:關于OneNote入庫處理以及稽核:http://www.cnblogs.com/baiboy/p/wpf3.html
【小記】:大膽嘗試才能突破,某個中醫藥大學有一批圖檔需要處理(ORC),然後進行資料挖掘。之前沒有接觸過ORC這個東西,但是還是應允了。在網上搜尋一番,關于中文圖檔識别,最終敲定為基于微軟的OneNote,其識别率相對較高。網上這個技術點的資料真心不多,後來于部落格園找到一篇博文,但是那個程式還是bug百出,而且隻是單處理。後來經過一番摸索逐個突破,批處理完成。然後進行界面設計,這些零碎工作完成後,便是入庫處理。由于OneNote生成的xml檔案封裝好的,即不可視的。便将其代碼處理生成txt檔案,再進行Oracle入庫處理。入庫前需要檔案内容稽核,并且在WPF開發中資料綁定和分頁中做了獨特處理。現在經過半個月的工作,本項目做個階段總結。一則知識總結便于二次開發,盡量保持程式流暢性,核心知識做以梳理;另外,相關WPF和OneNote常用技術共享,便于部分園友所需。本人技術有限,歡迎交流。項目還未結束,暫作階段文章釋出,随後相繼釋出。
篇二:基于OneNote難點突破和批量識别
【1】開篇概述:在對本章技術介紹前,還是梳理下思路。描述下本章功能和開發過程。做個系統大緻了解之後,在粘貼出本節效果圖配以完整代碼,然後分拆之,個體技術剖析。這樣既可以達到全局整體效果,也可以對局部技術或者知識點做以小結。功能看圖描述:本程式開發基于C#+WPF,然後這些條件具備前需要安裝office2010以上版本,包含OneNote即可
完整代碼:
namespace OnenoteOCRDemo
{
/// <summary>
/// Main.xaml 的互動邏輯
/// </summary>
public partial class Main : Window
{
#region 全局變量
private string __OutputFileName = string.Empty;
private WebClient client = new WebClient();
private delegate void UpdateProgressBarDelegate(System.Windows.DependencyProperty dp, Object value);
#endregion
#region 系統函數
public Main()
{
InitializeComponent();
}
#endregion
#region 使用者函數
#region 驗證檔案夾是否存在,以及是否為空 :2014-7-10 17:12:57
//驗證檔案夾是否存在,以及是否為空
//時間:2014-7-10 14:54:44
//作者:白甯超
private bool fn資料驗證()
{
if ((bool)this.rbtn本地圖檔.IsChecked)
{
if (!Directory.Exists(this.txtfile.Text))
{
this.labMsg.Content = "目錄不存在,重新選擇!";
this.txtfile.Focus();
return true;
}
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@txtfile.Text);
if (di.GetFiles().Length + di.GetDirectories().Length == 0)
{
this.labMsg.Content = "目錄為空!";
this.txtfile.Focus();
return true;
}
}
if (!Directory.Exists(this.txt輸出目錄.Text))
{
this.labMsg.Content = "輸出目錄不存在,請重新選擇。";
this.txt輸出目錄.Focus();
return true;
}
return false;
}
#endregion
#region 周遊出檔案中圖檔路徑
//檔案中選擇所有檔案處理
//時間:2014-7-10 17:17:29
//作者:白甯超
public List<string> GetImgPath(string Filepath)
{
DirectoryInfo d = new DirectoryInfo(Filepath);
ArrayList Flst = GetAll(d); //存放圖檔完整路徑
List<string> imgpath = new List<string>();
foreach (object o in Flst)
{
imgpath.Add(@txtfile.Text + "\\" + o.ToString());
}
return imgpath;//傳回圖檔路徑集合
}
#endregion
#region 擷取圖檔的過程
private void fnStartDownload(string v_strImgPath, string v_strOutputDir, out string v_strTmpPath)
{
int n = v_strImgPath.LastIndexOf('/');
string URLAddress = v_strImgPath.Substring(0, n);
string fileName = v_strImgPath.Substring(n + 1, v_strImgPath.Length - n - 1);
this.__OutputFileName = v_strOutputDir + "\\" + fileName.Substring(0, fileName.LastIndexOf(".")) + ".txt";
if (!Directory.Exists(System.Configuration.ConfigurationManager.AppSettings["tmpPath"]))
{
Directory.CreateDirectory(System.Configuration.ConfigurationManager.AppSettings["tmpPath"]);
}
string Dir = System.Configuration.ConfigurationManager.AppSettings["tmpPath"];
v_strTmpPath = Dir + "\\" + fileName;
this.client.DownloadFile(v_strImgPath, v_strTmpPath);
}
#endregion
#region//删除指定目錄下的所有檔案夾以及檔案
private void DelFillOrDir(string strPath)
{
if (Directory.GetDirectories(strPath).Length > 0 || Directory.GetFiles(strPath).Length > 0)
{
// 獲得檔案夾數組
string[] strDirs = System.IO.Directory.GetDirectories(strPath); // 獲得檔案數組
string[] strFiles = System.IO.Directory.GetFiles(strPath); // 周遊所有子檔案夾
foreach (string strFile in strFiles)
{
// 删除檔案夾
System.IO.File.Delete(strFile);
} // 周遊所有檔案
foreach (string strdir in strDirs)
{ // 删除檔案
System.IO.Directory.Delete(strdir, true);
}
} // 成功
}
#endregion
#region//删除檔案
public static bool DeleteFile(string xmlPath)
{
FileInfo newFile = new FileInfo(xmlPath);
if (newFile.Exists == true)
{
newFile.Delete();
return true;
}
else
{
return false;
}
}
#endregion
#region//删除xml資料
public void DeleteXML(string xpath)
{
var onenoteApp = new Microsoft.Office.Interop.OneNote.Application(); //onenote提供的API
string notebookXml;
onenoteApp.GetHierarchy(null, Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, out notebookXml);
var docc = XDocument.Parse(notebookXml);
var ns = docc.Root.Name.Namespace;
XDocument doc = XDocument.Load(xpath);
string author = "USER-";
XElement xe = (from db in
doc.Element(ns + "Page").Elements(ns + "Outline")
where db.Attribute("author").Value == author
select db).Single() as XElement;
try
{
xe.Remove();
doc.Save(xpath);
}
catch
{
}
}
#region OCR寫入Onenote和生成文字整個過程
//string xpath = @"C:\Users\Administrator\Desktop\OCR_Onenote\OnenoteOCR2.1\tmp.xml";
private void fnOCR(string v_strImgPath)
{
ORC(v_strImgPath);
}
public void ORC(string v_strImgPath)
{
FileInfo file = new FileInfo(v_strImgPath);
#region //擷取圖檔的Base64編碼
using (MemoryStream ms = new MemoryStream())
{
Bitmap bp = new Bitmap(v_strImgPath);
switch (file.Extension.ToLower())
{
case ".jpg":
bp.Save(ms, ImageFormat.Jpeg);
break;
case ".jpeg":
bp.Save(ms, ImageFormat.Jpeg);
break;
case ".gif":
bp.Save(ms, ImageFormat.Gif);
break;
case ".bmp":
bp.Save(ms, ImageFormat.Bmp);
break;
case ".tiff":
bp.Save(ms, ImageFormat.Tiff);
break;
case ".png":
bp.Save(ms, ImageFormat.Png);
break;
case ".emf":
bp.Save(ms, ImageFormat.Emf);
break;
default:
this.labMsg.Content = "不支援的圖檔格式。";
return;
}
byte[] buffer = ms.GetBuffer();
string _Base64 = Convert.ToBase64String(buffer);
#endregion
//向Onenote2010中插入圖檔
var onenoteApp = new Microsoft.Office.Interop.OneNote.Application(); //onenote提供的API
/***************************************************************************************/
string sectionID;
onenoteApp.OpenHierarchy(@"C:\Users\Administrator\Documents\OneNote 筆記本\個人\newfile.one", null, out sectionID, Microsoft.Office.Interop.OneNote.CreateFileType.cftSection);
string pageID = "{A975EE72-19C3-4C80-9C0E-EDA576DAB5C6}{1}{B0}";
onenoteApp.CreateNewPage(sectionID, out pageID, Microsoft.Office.Interop.OneNote.NewPageStyle.npsBlankPageNoTitle);
/********************************************************************************/
string notebookXml;
onenoteApp.GetHierarchy(null, Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, out notebookXml);
var doc = XDocument.Parse(notebookXml);
var ns = doc.Root.Name.Namespace;
var pageNode = doc.Descendants(ns + "Page").FirstOrDefault();
var existingPageId = pageNode.Attribute("ID").Value;
#region
if (pageNode != null)
{
//Image Type 隻支援這些類型:auto|png|emf|jpg
string ImgExtension = file.Extension.ToLower().Substring(1);
switch (ImgExtension)
{
case "jpg":
ImgExtension = "jpg";
break;
case "png":
ImgExtension = "png";
break;
case "emf":
ImgExtension = "emf";
break;
default:
ImgExtension = "auto";
break;
}
#endregion
var page = new XDocument(new XElement(ns + "Page",
new XElement(ns + "Outline",
new XElement(ns + "OEChildren",
new XElement(ns + "OE",
new XElement(ns + "Image",
new XAttribute("format", ImgExtension), new XAttribute("originalPageNumber", "0"),
new XElement(ns + "Position",
new XAttribute("x", "0"), new XAttribute("y", "0"), new XAttribute("z", "0")),
new XElement(ns + "Size",
new XAttribute("width", bp.Width.ToString()), new XAttribute("height", bp.Height.ToString())),
new XElement(ns + "Data", _Base64)))))));
page.Root.SetAttributeValue("ID", existingPageId);
//儲存圖檔進入Onenote頁面
//注意以下幾點:(待解決)
//1,onenote頁面自動會生成一個頁面,可能造成一直ocr錯誤。删除預設頁面,建立空頁
//2,圖檔存儲在建立頁面中,通過如下代碼實作的,以追加存儲方式進行。
onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue);
//線程休眠時間,機關毫秒,若圖檔很大,則延長休眠時間,保證Onenote OCR完畢
System.Threading.Thread.Sleep(Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["WaitTIme"]));
string pageXml;
onenoteApp.GetPageContent(existingPageId, out pageXml, Microsoft.Office.Interop.OneNote.PageInfo.piBinaryData);
//擷取OCR後的内容
FileStream tmpXml = new FileStream(System.Configuration.ConfigurationManager.AppSettings["tmpPath"] + @"\tmp.xml", FileMode.Create, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(tmpXml);
sw.Write(pageXml);
sw.Flush();
sw.Close();
tmpXml.Close();
//加載xml中的資料
FileStream tmpOnenote = new FileStream(System.Configuration.ConfigurationManager.AppSettings["tmpPath"] + @"\tmp.xml", FileMode.Open, FileAccess.ReadWrite);
XmlReader reader = XmlReader.Create(tmpOnenote);
XElement rdlc = XElement.Load(reader);
// rdlc.Save(xpath);
/*****************************************************************************************************/
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager mgr = new XmlNamespaceManager(nameTable);
mgr.AddNamespace("one", ns.ToString());
StringReader sr = new StringReader(pageXml);
XElement onenote = XElement.Load(sr);
////讀取xml中資料,并儲存到文本中。
//XDocument doc1 = XDocument.Load(xpath);
var xml = from o in onenote.XPathSelectElements("//one:Image", mgr)
select o.XPathSelectElement("//one:OCRText", mgr).Value;
this.txtOCRed.Text = xml.First().ToString();
/**********************************************************************/
sr.Close();
reader.Close();
tmpOnenote.Close();
//DeleteXML(xpath);
onenoteApp.DeleteHierarchy(existingPageId);
//onenoteApp.DeletePageContent(existingPageId, "{242BE490-7BF9-43D5-B719-3999E7631259}{46}{B0}");
//onenoteApp.DeletePageContent(existingPageId, "{242BE490-7BF9-43D5-B719-3999E7631259}{50}{B0}");
}
}
}
#endregion
#endregion
#endregion
#region 系統事件
#region 搜尋檔案夾中的檔案:2014-7-10 17:12:57
//搜尋檔案夾中的檔案
//時間:2014-7-10 14:54:44
//作者:白甯超
ArrayList GetAll(DirectoryInfo dir)
{
try
{
ArrayList FileList = new ArrayList();//定義數組存放圖檔檔案名
FileInfo[] allFile = dir.GetFiles();
foreach (FileInfo fi in allFile)
{
FileList.Add(fi.Name);//周遊圖檔,并添加到數組
}
DirectoryInfo[] allDir = dir.GetDirectories();
foreach (DirectoryInfo d in allDir)
{
GetAll(d);
}
return FileList;
}
catch (Exception e)
{
labMsg.Content = e.Message + "檔案夾選擇方式錯誤,重新選擇!!";
return null;
}
}
#endregion
#region 選擇周遊檔案夾圖檔
//檔案中選擇所有檔案處理
//時間:2014-7-10 14:54:44
//作者:白甯超
private void btn浏覽_Click(object sender, RoutedEventArgs e)
{
txtmulu.Text = null;
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.Description = "請選擇待處理目錄";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string foldPath = dialog.SelectedPath;
txtfile.Text = foldPath;
DirectoryInfo d = new DirectoryInfo(@txtfile.Text);
ArrayList Flst = GetAll(d);
foreach (object o in Flst)
{
txtmulu.Text += "正在ORC圖檔: 【" + o.ToString() + "】\r\n";
}
}
else
{
labMsg.Content = "打開失敗!!";
}
#region 上傳單個圖檔 2014-7-10 15:34:17
/*OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "請選擇一個本地圖檔";
ofd.Multiselect = false;
ofd.Filter = "支援的圖檔格式(*.jpg,*.jpeg,*.gif,*.bmp,*.png,*.tiff,*.emf)|*.jpg;*.jpeg;*.gif;*.bmp;*.png;*.tiff;*.emf";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
this.txt本地圖檔.Text = ofd.FileName;
this.img圖檔.Source = new BitmapImage(new Uri(ofd.FileName, UriKind.RelativeOrAbsolute));
this.labMsg.Content = "本地圖檔已成功加載。";
}*/
#endregion
}
#endregion
#region 選擇本地圖檔OCR轉化
private void rbtn本地圖檔_Checked(object sender, RoutedEventArgs e)
{
if (this.IsInitialized)
{
if ((bool)this.rbtn本地圖檔.IsChecked)
{
this.txtfile.Text = string.Empty;
this.txtfile.IsEnabled = true;
this.btn浏覽.IsEnabled = true;
this.txtfile.Focus();
this.txtmulu.Text = null;
}
}
}
#endregion
#region 選擇需要輸入處理的檔案
private void btn浏覽_Click_1(object sender, RoutedEventArgs e)
{
txtmulu.Text = null;
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.Description = "請選擇待處理目錄";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string foldPath = dialog.SelectedPath;
txtfile.Text = foldPath;
DirectoryInfo d = new DirectoryInfo(@txtfile.Text);
ArrayList Flst = GetAll(d);
foreach (object o in Flst)
{
txtmulu.Text += "正在ORC圖檔: 【" + o.ToString() + "】\r\n";
}
}
else
{
labMsg.Content = "打開失敗!!";
}
#region 上傳單個圖檔 2014-7-10 15:34:17
/*OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "請選擇一個本地圖檔";
ofd.Multiselect = false;
ofd.Filter = "支援的圖檔格式(*.jpg,*.jpeg,*.gif,*.bmp,*.png,*.tiff,*.emf)|*.jpg;*.jpeg;*.gif;*.bmp;*.png;*.tiff;*.emf";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
this.txt本地圖檔.Text = ofd.FileName;
this.img圖檔.Source = new BitmapImage(new Uri(ofd.FileName, UriKind.RelativeOrAbsolute));
this.labMsg.Content = "本地圖檔已成功加載。";
}*/
#endregion
}
#endregion
#region 選擇輸出檔案夾
private void btn輸出浏覽_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.Description = "請選擇一個輸出目錄";
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
this.txt輸出目錄.Text = fbd.SelectedPath;
DelFillOrDir(this.txt輸出目錄.Text);
}
}
#endregion
#region 清空輸出檔案
private void btn清空_Click(object sender, RoutedEventArgs e)
{
OCRtxt.Text = "";
this.OCRtxt.Focus();
}
#endregion
#region ORC轉化過程
private void btnOCR_Click(object sender, RoutedEventArgs e)
{
if (this.fn資料驗證())
{
OCRtxt.Text = "";
return;
}
try
{
DirectoryInfo dir = new DirectoryInfo(this.txt輸出目錄.Text);
if ((bool)this.rbtn本地圖檔.IsChecked)
{
List<string> imgpath = GetImgPath(@txtfile.Text);//擷取圖檔清單
//定義進度條預設值
pb_import.Minimum = 0;
pb_import.Maximum = imgpath.Count();
double i = 0;
txtOCRed.Text = "";
OCRtxt.Text += "******************************************************************************";
foreach (object img in imgpath)
{
this.fnOCR(img.ToString());//周遊處理圖檔orc
FileInfo file = new FileInfo(img.ToString());
string name = file.Name.Substring(0, file.Name.LastIndexOf("."));
this.__OutputFileName = dir.FullName + @"\" + name + ".txt";
FileStream fs = new FileStream(this.__OutputFileName, FileMode.Create, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.Write(this.txtOCRed.Text);//将this.txtOCRed.Text内容寫進txt檔案中
sw.Flush();
sw.Close();
fs.Close();
OCRtxt.Text += "成功ORC出: 【" + name + ".txt】" + "\r\n";
//回調UI進度顯示
i++;
pb_import.Value = i;
UpdateProgressBarDelegate updatePbDelegate = new UpdateProgressBarDelegate(pb_import.SetValue);
Dispatcher.Invoke(updatePbDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { System.Windows.Controls.ProgressBar.ValueProperty, Convert.ToDouble(i + 1) });
Thread.Sleep(1000);
}
}
if (pb_import.Value == pb_import.Maximum)
{
System.Windows.Forms.MessageBox.Show("資料轉換完成。");
}
else
{
System.Windows.Forms.MessageBox.Show("資料轉換失敗。");
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("資料轉換失敗:" + ex.Message + ex.StackTrace);
this.labMsg.Content = "OCR失敗。";
}
finally {
//System.Threading.Thread.CurrentThread.Abort();
Thread.Sleep(3000);
}
}
#endregion
#region//窗體關閉
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
DirectoryInfo dir = new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["tmpPath"]);
foreach (FileInfo file in dir.GetFiles())
{
file.Delete();
}
}
#endregion
#endregion
}
}
功能以及操作描述:
- 運作本頁面如上圖,然後通過選擇待處理目錄(含中文文字圖檔),和輸出目錄,點選ORC即可。
- 在待處理目錄下,點選浏覽按鈕,然後選擇相應的檔案夾,背景通過判斷檔案夾是否存在,如果存在進行周遊,讀取出所有圖檔,然後在本頁左端文本框對圖檔進行顯示。
- 然後選擇輸出目錄中的浏覽按鈕,選擇處理後的結果存放檔案夾,此項必填。否則不執行。在每次操作浏覽按鈕時,會對選擇的檔案夾進行清空處理,這樣下次操作保持幹淨資料。
- 完成以上步驟,可以進行ORC操作,操作過程中通過周遊檔案夾中圖檔檔案,在一個方面中打開OneNote接口,對圖檔進行處理。圖檔處理生成的是一個xml檔案,此檔案不可視,一個緩存的xml檔案,随着程式結束而終止,在處理過程中通過代碼解析緩存xml,将文本資料提取到一個txt檔案中。同時沒執行一張圖檔,如圖左邊列印成功執行的檔案,同時進度條滾動,結束後進行提示。
- 最後打開對應檔案夾裡面顯示生産資料與對應圖檔保持一緻。規範字型識别率還是可以的
所遇問題以及瓶頸突破:
- 在描述難點之前,我還是先提取出核心ORC代碼,下面再做以概述。周遊處理圖檔
#region
foreach (object img in imgpath)
{
this.fnOCR(img.ToString());//周遊處理圖檔orc
FileInfo file = new FileInfo(img.ToString());
string name = file.Name.Substring(0, file.Name.LastIndexOf("."));
this.__OutputFileName = dir.FullName + @"\" + name + ".txt";
FileStream fs = new FileStream(this.__OutputFileName, FileMode.Create, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.Write(this.txtOCRed.Text);//将this.txtOCRed.Text内容寫進txt檔案中
sw.Flush();
sw.Close();
fs.Close();
OCRtxt.Text += "成功ORC出: 【" + name + ".txt】" + "\r\n";
//回調UI進度顯示
i++;
pb_import.Value = i;
UpdateProgressBarDelegate updatePbDelegate = new UpdateProgressBarDelegate(pb_import.SetValue);
Dispatcher.Invoke(updatePbDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { System.Windows.Controls.ProgressBar.ValueProperty, Convert.ToDouble(i + 1) });
Thread.Sleep(1000);
}
#endregion
- fnOCR圖檔處理核心代碼:下面截取核心代碼,詳細見付碼
public void ORC(string v_strImgPath) { FileInfo file = new FileInfo(v_strImgPath); //向Onenote2010中插入圖檔 var onenoteApp = new Microsoft.Office.Interop.OneNote.Application(); //onenote提供的API /***************************************************************************************/ string sectionID; onenoteApp.OpenHierarchy(@"C:\Users\Administrator\Documents\OneNote 筆記本\個人\newfile.one", null, out sectionID, Microsoft.Office.Interop.OneNote.CreateFileType.cftSection); string pageID = "{A975EE72-19C3-4C80-9C0E-EDA576DAB5C6}{1}{B0}"; onenoteApp.CreateNewPage(sectionID, out pageID, Microsoft.Office.Interop.OneNote.NewPageStyle.npsBlankPageNoTitle); /********************************************************************************/ string notebookXml; onenoteApp.GetHierarchy(null, Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, out notebookXml); var doc = XDocument.Parse(notebookXml); var ns = doc.Root.Name.Namespace; var pageNode = doc.Descendants(ns + "Page").FirstOrDefault(); var existingPageId = pageNode.Attribute("ID").Value; var page = new XDocument(new XElement(ns + "Page", new XElement(ns + "Outline", new XElement(ns + "OEChildren", new XElement(ns + "OE", new XElement(ns + "Image", new XAttribute("format", ImgExtension), new XAttribute("originalPageNumber", "0"), new XElement(ns + "Position", new XAttribute("x", "0"), new XAttribute("y", "0"), new XAttribute("z", "0")), new XElement(ns + "Size", new XAttribute("width", bp.Width.ToString()), new XAttribute("height", bp.Height.ToString())), new XElement(ns + "Data", _Base64))))))); page.Root.SetAttributeValue("ID", existingPageId); //儲存圖檔進入Onenote頁面 //注意以下幾點:(待解決) //1,onenote頁面自動會生成一個頁面,可能造成一直ocr錯誤。删除預設頁面,建立空頁 //2,圖檔存儲在建立頁面中,通過如下代碼實作的,以追加存儲方式進行。 onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue); //線程休眠時間,機關毫秒,若圖檔很大,則延長休眠時間,保證Onenote OCR完畢 System.Threading.Thread.Sleep(Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["WaitTIme"])); string pageXml; onenoteApp.GetPageContent(existingPageId, out pageXml, Microsoft.Office.Interop.OneNote.PageInfo.piBinaryData); //擷取OCR後的内容 FileStream tmpXml = new FileStream(System.Configuration.ConfigurationManager.AppSettings["tmpPath"] + @"\tmp.xml", FileMode.Create, FileAccess.ReadWrite); StreamWriter sw = new StreamWriter(tmpXml); sw.Write(pageXml); sw.Flush(); sw.Close(); tmpXml.Close(); //加載xml中的資料 FileStream tmpOnenote = new FileStream(System.Configuration.ConfigurationManager.AppSettings["tmpPath"] + @"\tmp.xml", FileMode.Open, FileAccess.ReadWrite); XmlReader reader = XmlReader.Create(tmpOnenote); XElement rdlc = XElement.Load(reader); /*****************************************************************************************************/ XmlNameTable nameTable = reader.NameTable; XmlNamespaceManager mgr = new XmlNamespaceManager(nameTable); mgr.AddNamespace("one", ns.ToString()); StringReader sr = new StringReader(pageXml); XElement onenote = XElement.Load(sr); ////讀取xml中資料,并儲存到文本中。 //XDocument doc1 = XDocument.Load(xpath); var xml = from o in onenote.XPathSelectElements("//one:Image", mgr) select o.XPathSelectElement("//one:OCRText", mgr).Value; this.txtOCRed.Text = xml.First().ToString(); /**********************************************************************/ sr.Close(); reader.Close(); tmpOnenote.Close(); onenoteApp.DeleteHierarchy(existingPageId); } } }
問題繼續描述,未加入如上代碼時,暫且不說批處理,即便是單處理。結果是無論加載多少張圖檔,可以生成對應txt檔案,但是對應的所有txt檔案裡面文本内容始終一樣。解決方案分析下:
- 是文本生成問題,于是想到每次圖檔生成清理出前一個xml,但是無論如何找不到xml存在,後來斷點調試發現,執行onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue);之後,打開Onenote頁面會發現圖檔出來,說明onenote已經在處理,此刻xml已經生成。接下來 onenoteApp.GetPageContent(existingPageId, out pageXml, Microsoft.Office.Interop.OneNote.PageInfo.piBinaryData);方法把不可見的xml以字元串形式pageXml顯示處理,後面就是對其處理了。證明從xml着手是不能解決問題的。
- 接下來就是想另一個方案:采用接口提供的DeletePageContent方法,但是面臨問題在于其需要兩個參數(頁面序列id,和圖檔id),對于頁面序列id通過斷點可以找到,但是圖檔是随機的,id無法控制。是以此方案失敗。
3. 在讀取xml中發現this.txtOCRed.Text = xml.First().ToString();那麼讓去每次讀取最後一條資料不就ok?對,,肯定這樣,抱着堅定信心解決半日不得解。斷點再經調試發現,讀取的xml是不可控的,即是緩存中xml以輸出參數,輸出的字元串的處理。最終還不得解決。為此困惑數日。
4. 那麼在生成的緩存xml重新放置到建立的xml中,然後每次讀取一條結束,删除本次記錄。問題肯定解決的,大喜,于是做出如下構造:
#region//删除xml資料
public void DeleteXML(string xpath)
{
var onenoteApp = new Microsoft.Office.Interop.OneNote.Application(); //onenote提供的API
string notebookXml;
onenoteApp.GetHierarchy(null, Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, out notebookXml);
var docc = XDocument.Parse(notebookXml);
var ns = docc.Root.Name.Namespace;
XDocument doc = XDocument.Load(xpath);
string author = "USER-";
XElement xe = (from db in
doc.Element(ns + "Page").Elements(ns + "Outline")
where db.Attribute("author").Value == author
select db).Single() as XElement;
try
{
xe.Remove();
doc.Save(xpath);
}
catch
{
}
}
#region OCR寫入Onenote和生成文字整個過程
//string xpath = @"C:\Users\Administrator\Desktop\OCR_Onenote\OnenoteOCR2.1\tmp.xml";
private void fnOCR(string v_strImgPath)
{
ORC(v_strImgPath);
}
public void ORC(string v_strImgPath)
{
FileInfo file = new FileInfo(v_strImgPath);
#region //擷取圖檔的Base64編碼
using (MemoryStream ms = new MemoryStream())
{
Bitmap bp = new Bitmap(v_strImgPath);
switch (file.Extension.ToLower())
{
case ".jpg":
bp.Save(ms, ImageFormat.Jpeg);
break;
case ".jpeg":
bp.Save(ms, ImageFormat.Jpeg);
break;
case ".gif":
bp.Save(ms, ImageFormat.Gif);
break;
case ".bmp":
bp.Save(ms, ImageFormat.Bmp);
break;
case ".tiff":
bp.Save(ms, ImageFormat.Tiff);
break;
case ".png":
bp.Save(ms, ImageFormat.Png);
break;
case ".emf":
bp.Save(ms, ImageFormat.Emf);
break;
default:
this.labMsg.Content = "不支援的圖檔格式。";
return;
}
byte[] buffer = ms.GetBuffer();
string _Base64 = Convert.ToBase64String(buffer);
#endregion
//向Onenote2010中插入圖檔
var onenoteApp = new Microsoft.Office.Interop.OneNote.Application(); //onenote提供的API
/***************************************************************************************/
string sectionID;
onenoteApp.OpenHierarchy(@"C:\Users\Administrator\Documents\OneNote 筆記本\個人\newfile.one", null, out sectionID, Microsoft.Office.Interop.OneNote.CreateFileType.cftSection);
string pageID = "{A975EE72-19C3-4C80-9C0E-EDA576DAB5C6}{1}{B0}";
onenoteApp.CreateNewPage(sectionID, out pageID, Microsoft.Office.Interop.OneNote.NewPageStyle.npsBlankPageNoTitle);
/********************************************************************************/
string notebookXml;
onenoteApp.GetHierarchy(null, Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, out notebookXml);
var doc = XDocument.Parse(notebookXml);
var ns = doc.Root.Name.Namespace;
var pageNode = doc.Descendants(ns + "Page").FirstOrDefault();
var existingPageId = pageNode.Attribute("ID").Value;
#region
if (pageNode != null)
{
//Image Type 隻支援這些類型:auto|png|emf|jpg
string ImgExtension = file.Extension.ToLower().Substring(1);
switch (ImgExtension)
{
case "jpg":
ImgExtension = "jpg";
break;
case "png":
ImgExtension = "png";
break;
case "emf":
ImgExtension = "emf";
break;
default:
ImgExtension = "auto";
break;
}
#endregion
var page = new XDocument(new XElement(ns + "Page",
new XElement(ns + "Outline",
new XElement(ns + "OEChildren",
new XElement(ns + "OE",
new XElement(ns + "Image",
new XAttribute("format", ImgExtension), new XAttribute("originalPageNumber", "0"),
new XElement(ns + "Position",
new XAttribute("x", "0"), new XAttribute("y", "0"), new XAttribute("z", "0")),
new XElement(ns + "Size",
new XAttribute("width", bp.Width.ToString()), new XAttribute("height", bp.Height.ToString())),
new XElement(ns + "Data", _Base64)))))));
page.Root.SetAttributeValue("ID", existingPageId);
//儲存圖檔進入Onenote頁面
//注意以下幾點:(待解決)
//1,onenote頁面自動會生成一個頁面,可能造成一直ocr錯誤。删除預設頁面,建立空頁
//2,圖檔存儲在建立頁面中,通過如下代碼實作的,以追加存儲方式進行。
onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue);
//線程休眠時間,機關毫秒,若圖檔很大,則延長休眠時間,保證Onenote OCR完畢
System.Threading.Thread.Sleep(Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["WaitTIme"]));
string pageXml;
onenoteApp.GetPageContent(existingPageId, out pageXml, Microsoft.Office.Interop.OneNote.PageInfo.piBinaryData);
//擷取OCR後的内容
FileStream tmpXml = new FileStream(System.Configuration.ConfigurationManager.AppSettings["tmpPath"] + @"\tmp.xml", FileMode.Create, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(tmpXml);
sw.Write(pageXml);
sw.Flush();
sw.Close();
tmpXml.Close();
//加載xml中的資料
FileStream tmpOnenote = new FileStream(System.Configuration.ConfigurationManager.AppSettings["tmpPath"] + @"\tmp.xml", FileMode.Open, FileAccess.ReadWrite);
XmlReader reader = XmlReader.Create(tmpOnenote);
XElement rdlc = XElement.Load(reader);
// rdlc.Save(xpath);
/*****************************************************************************************************/
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager mgr = new XmlNamespaceManager(nameTable);
mgr.AddNamespace("one", ns.ToString());
StringReader sr = new StringReader(pageXml);
XElement onenote = XElement.Load(sr);
////讀取xml中資料,并儲存到文本中。
//XDocument doc1 = XDocument.Load(xpath);
var xml = from o in onenote.XPathSelectElements("//one:Image", mgr)
select o.XPathSelectElement("//one:OCRText", mgr).Value;
this.txtOCRed.Text = xml.First().ToString();
/**********************************************************************/
sr.Close();
reader.Close();
tmpOnenote.Close();
//DeleteXML(xpath);
onenoteApp.DeleteHierarchy(existingPageId);
//onenoteApp.DeletePageContent(existingPageId, "{242BE490-7BF9-43D5-B719-3999E7631259}{46}{B0}");
//onenoteApp.DeletePageContent(existingPageId, "{242BE490-7BF9-43D5-B719-3999E7631259}{50}{B0}");
}
}
}
#endregion
#endregion
結果還是無濟于事,關鍵還是緩存的xml無法清理。
解決方案:搞定淩晨,無意間打開幾篇英文文章(文章看不懂,隻看代碼),發現其原理在于圖檔處理過程中,催毀原始頁面,建立頁面即可。
1 2 3 4 5 6 7 | |
調用API中建立頁面方法CreateNewPage,pageID通過斷點可以調試到,sectionID找到本地的位址即可。然後在執行一條資料結束時,調用onenoteApp.DeleteHierarchy(existingPageId)即可。
止于此核心問題解決,下面總結下所用的檔案相關操作:
1 、驗證檔案夾是否存在,以及是否為空
#region 驗證檔案夾是否存在,以及是否為空 :2014-7-10 17:12:57
//驗證檔案夾是否存在,以及是否為空
//時間:2014-7-10 14:54:44
//作者:白甯超
private bool fn資料驗證()
{
if ((bool)this.rbtn本地圖檔.IsChecked)
{
if (!Directory.Exists(this.txtfile.Text))
{
this.labMsg.Content = "目錄不存在,重新選擇!";
this.txtfile.Focus();
return true;
}
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@txtfile.Text);
if (di.GetFiles().Length + di.GetDirectories().Length == 0)
{
this.labMsg.Content = "目錄為空!";
this.txtfile.Focus();
return true;
}
}
if (!Directory.Exists(this.txt輸出目錄.Text))
{
this.labMsg.Content = "輸出目錄不存在,請重新選擇。";
this.txt輸出目錄.Focus();
return true;
}
return false;
}
#endregion
2、周遊出檔案中圖檔路徑
#region 周遊出檔案中圖檔路徑
//檔案中選擇所有檔案處理
//時間:2014-7-10 17:17:29
//作者:白甯超
public List<string> GetImgPath(string Filepath)
{
DirectoryInfo d = new DirectoryInfo(Filepath);
ArrayList Flst = GetAll(d); //存放圖檔完整路徑
List<string> imgpath = new List<string>();
foreach (object o in Flst)
{
imgpath.Add(@txtfile.Text + "\\" + o.ToString());
}
return imgpath;//傳回圖檔路徑集合
}
#endregion
3、擷取圖檔的過程
#region 擷取圖檔的過程
private void fnStartDownload(string v_strImgPath, string v_strOutputDir, out string v_strTmpPath)
{
int n = v_strImgPath.LastIndexOf('/');
string URLAddress = v_strImgPath.Substring(0, n);
string fileName = v_strImgPath.Substring(n + 1, v_strImgPath.Length - n - 1);
this.__OutputFileName = v_strOutputDir + "\\" + fileName.Substring(0, fileName.LastIndexOf(".")) + ".txt";
if (!Directory.Exists(System.Configuration.ConfigurationManager.AppSettings["tmpPath"]))
{
Directory.CreateDirectory(System.Configuration.ConfigurationManager.AppSettings["tmpPath"]);
}
string Dir = System.Configuration.ConfigurationManager.AppSettings["tmpPath"];
v_strTmpPath = Dir + "\\" + fileName;
this.client.DownloadFile(v_strImgPath, v_strTmpPath);
}
#endregion
4、删除指定目錄下的所有檔案夾以及檔案
#region//删除指定目錄下的所有檔案夾以及檔案
private void DelFillOrDir(string strPath)
{
if (Directory.GetDirectories(strPath).Length > 0 || Directory.GetFiles(strPath).Length > 0)
{
// 獲得檔案夾數組
string[] strDirs = System.IO.Directory.GetDirectories(strPath); // 獲得檔案數組
string[] strFiles = System.IO.Directory.GetFiles(strPath); // 周遊所有子檔案夾
foreach (string strFile in strFiles)
{
// 删除檔案夾
System.IO.File.Delete(strFile);
} // 周遊所有檔案
foreach (string strdir in strDirs)
{ // 删除檔案
System.IO.Directory.Delete(strdir, true);
}
} // 成功
}
#endregion
5、删除檔案
#region//删除檔案
public static bool DeleteFile(string xmlPath)
{
FileInfo newFile = new FileInfo(xmlPath);
if (newFile.Exists == true)
{
newFile.Delete();
return true;
}
else
{
return false;
}
}
#endregion
6、删除xml資料
View Code
7、搜尋檔案夾中的檔案
#region 搜尋檔案夾中的檔案:2014-7-10 17:12:57
//搜尋檔案夾中的檔案
//時間:2014-7-10 14:54:44
//作者:白甯超
ArrayList GetAll(DirectoryInfo dir)
{
try
{
ArrayList FileList = new ArrayList();//定義數組存放圖檔檔案名
FileInfo[] allFile = dir.GetFiles();
foreach (FileInfo fi in allFile)
{
FileList.Add(fi.Name);//周遊圖檔,并添加到數組
}
DirectoryInfo[] allDir = dir.GetDirectories();
foreach (DirectoryInfo d in allDir)
{
GetAll(d);
}
return FileList;
}
catch (Exception e)
{
labMsg.Content = e.Message + "檔案夾選擇方式錯誤,重新選擇!!";
return null;
}
}
#endregion
8、選擇周遊檔案夾圖檔
private void btn浏覽_Click(object sender, RoutedEventArgs e)
{
txtmulu.Text = null;
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.Description = "請選擇待處理目錄";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string foldPath = dialog.SelectedPath;
txtfile.Text = foldPath;
DirectoryInfo d = new DirectoryInfo(@txtfile.Text);
ArrayList Flst = GetAll(d);
foreach (object o in Flst)
{
txtmulu.Text += "正在ORC圖檔: 【" + o.ToString() + "】\r\n";
}
}
else
{
labMsg.Content = "打開失敗!!";
}
#region 上傳單個圖檔 2014-7-10 15:34:17
/*OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "請選擇一個本地圖檔";
ofd.Multiselect = false;
ofd.Filter = "支援的圖檔格式(*.jpg,*.jpeg,*.gif,*.bmp,*.png,*.tiff,*.emf)|*.jpg;*.jpeg;*.gif;*.bmp;*.png;*.tiff;*.emf";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
this.txt本地圖檔.Text = ofd.FileName;
this.img圖檔.Source = new BitmapImage(new Uri(ofd.FileName, UriKind.RelativeOrAbsolute));
this.labMsg.Content = "本地圖檔已成功加載。";
}*/
#endregion
}
9、窗體關閉
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
DirectoryInfo dir = new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["tmpPath"]);
foreach (FileInfo file in dir.GetFiles())
{
file.Delete();
}
}
【補充】orc前後結果對照:應部分園友建議,更為直覺
- 整體orc結果:
- 具體orc結果:
【篇末】:程式中使用周遊檔案,檔案夾清空處理,檔案的删除,檔案的查找,檔案夾的判空,重點在于圖檔的OneNote處理等操作,完成了批處理。可以自動執行批檔案夾中圖檔,生成新的文本檔案與圖檔名一緻。現在不足之處,對檔案夾的檔案類型篩選為執行圖檔類型沒有處理,容錯不足,這個自己用檔案放入純圖檔可以,另外有時候程序處理不穩定,估計加入進度條原因。待版本2再做改進。下一節介紹文本檔案處理入庫(Oracle)。特别wpf中DataGrid的使用,如何在wpf中完成分頁,簡單的集合類型資料庫分頁可以,但是資料庫連接配接如何分頁?
http://www.cnblogs.com/baiboy