private void OCR()
{
//tessnet2.Tesseract ocr = new tessnet2.Tesseract();//声明一个OCR类
tessnet2.Tesseract ocr = null;
string defaultCharList = "0123456789";
ocr = new tessnet2.Tesseract();
ocr.SetVariable("tessedit_char_whitelist", defaultCharList);//设置识别变量,当前只能识别数字及英文字符。
ocr.Init(Application.StartupPath + @"\tessdata", "eng", false); //应用当前语言包。注,Tessnet2是支持多国语的。语言包下载链接:http://code.google.com/p/tesseract-ocr/downloads/list WebClient wc = new WebClient();
byte[] oimg = wc.DownloadData(txtImageUrl.Text); // 自己修改成要识别的地址吧
Bitmap bp = new Bitmap(new MemoryStream(oimg), true);//识别图像
Bitmap bp2 = new Bitmap(new MemoryStream(oimg), true);
picBox1.Image = bp2;
//bp = ImageProcess.RemoveGreen(bp);
//bp = ImageProcess.ToBW(bp); picBox2.Image = bp; List<tessnet2.Word> result = new List<tessnet2.Word>();
string txt = ""; try
{
result = ocr.DoOCR(bp, Rectangle.Empty);//执行识别操作
foreach (tessnet2.Word word in result)//遍历识别结果。
{
txt += word.Text;
}
}
catch (Exception ex)
{ }
textBox1.Text = txt;
}
}网上下的源码。每调用一次内存就增加2m。直到内存超限,应用程序自动关闭。求大神怎么解决
{
//tessnet2.Tesseract ocr = new tessnet2.Tesseract();//声明一个OCR类
tessnet2.Tesseract ocr = null;
string defaultCharList = "0123456789";
ocr = new tessnet2.Tesseract();
ocr.SetVariable("tessedit_char_whitelist", defaultCharList);//设置识别变量,当前只能识别数字及英文字符。
ocr.Init(Application.StartupPath + @"\tessdata", "eng", false); //应用当前语言包。注,Tessnet2是支持多国语的。语言包下载链接:http://code.google.com/p/tesseract-ocr/downloads/list WebClient wc = new WebClient();
byte[] oimg = wc.DownloadData(txtImageUrl.Text); // 自己修改成要识别的地址吧
Bitmap bp = new Bitmap(new MemoryStream(oimg), true);//识别图像
Bitmap bp2 = new Bitmap(new MemoryStream(oimg), true);
picBox1.Image = bp2;
//bp = ImageProcess.RemoveGreen(bp);
//bp = ImageProcess.ToBW(bp); picBox2.Image = bp; List<tessnet2.Word> result = new List<tessnet2.Word>();
string txt = ""; try
{
result = ocr.DoOCR(bp, Rectangle.Empty);//执行识别操作
foreach (tessnet2.Word word in result)//遍历识别结果。
{
txt += word.Text;
}
}
catch (Exception ex)
{ }
textBox1.Text = txt;
}
}网上下的源码。每调用一次内存就增加2m。直到内存超限,应用程序自动关闭。求大神怎么解决
{
...
}然后WebClient也应该释放,最好也用using括起来, picBox1.Image = bp2;
picBox2.Image = bp;赋值之前也应该释放原来的bitmap,if (picBox1.Image!=null)
{
Bitmap toRemove=picBox1.Image;
picBox1.Image=null;
toRemove.Dispose();
}
if (picBox2.Image!=null)
{
Bitmap toRemove=picBox2.Image;
picBox2.Image=null;
toRemove.Dispose();
}
picBox1.Image = bp2;
picBox2.Image = bp;
try
{
result = ocr.DoOCR(bp, Rectangle.Empty);//执行识别操作
foreach (tessnet2.Word word in result)//遍历识别结果。
{
txt += word.Text;
}
}
catch (Exception ex)
{ }我去掉这段代码执行程序是每问题的。
要用StringBuilder,去网上查查。
ocr是什么东西我不懂,你自己看看是不是什么东西开启了为释放理论上将如果你的result如果不是很大应该到不了2M,如果你的result里面的对象tessnet2.Word 非常多就会达到2M甚至更多,所需要注意啊。
ocr有Dispose方法。但是我调用了没有作用。还是耗内存。最大的疑点就是这句了:ocr.DoOCR(bp, Rectangle.Empty);
其他的应该都是没有问题的。
每次执行完,就强制回收下,
如果确实像楼主说的那样,问题出在ocr的话,可尝试下面
try
{
result = ocr.DoOCR(bp, Rectangle.Empty);//执行识别操作
foreach (tessnet2.Word word in result)//遍历识别结果。
{
txt += word.Text;
}
}
catch (Exception ex)
{ }
finally
{
ocr.Dispose();
}如果还没有效果,那就是ocr本事的问题:它内部使用的资源没有在Dispose()方法里释放掉
GC如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器,在不至于混淆的情况下也成为GC)以应用程序的root为基础.
GC实现原理:
通过识别它们是否被引用来确定哪些对象是已经死亡的、哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收。这就是GC工作的原理
为了实现这个原理,GC有多种算法。比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.NET CLR,Java VM和Rotor都是采用的Mark Sweep算法
具体算法,我也不太了解.这里就不说了!
先上代码:.NET的GC机制有这样两个问题:
第一,GC只能回收内存中的托管对象资源,对于非托管对象例如:数据库连接,文件句柄关于很多直接和硬件打交道的资源,GC是不能涉及的。
第二,GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性,因此.Net中GC会在某一个时间点去回收垃圾.class Program
{
static string name = "张三";
static void Main(string[] args)
{
//判断静态对象是否被回收
GC.Collect();//强制对所有代进行即时垃圾回收。
WeakReference weakstatic = new WeakReference(name);//引用指定的对象初始化 WeakReference 类的新实例。
Console.WriteLine("静态变量是否存活:" + weakstatic.IsAlive);
//被引用的对象是否被回收
List<Person> persons = new List<Person>();
for (int i = 0; i < 9000; i++ ){
Person p = new Person();
}
GC.Collect();
WeakReference weakReference = new WeakReference(persons);
Console.WriteLine("被引用的对象是否存活:" + weakReference.IsAlive);
//没有被引用的对象是否被回收
Person p1 = new Person();
WeakReference weakNo = new WeakReference(p1);
GC.Collect();
Console.WriteLine("没有被引用的对象是否存活:" + weakNo.IsAlive);
/*
总结:
* 托管内存中的对象,只要有被引用到的地方,GC不会回收,
* 只要没有被任何地方引用的对象GC会回收,但是不是立即回收,GC会找个时间段统一回收
*/
Console.WriteLine("");
Console.WriteLine("解析:为什么没有被引用的对象是否被回收?是因为GC并不是实时性的,\n这将会造成系统性能上的瓶颈和不确定性,因此.Net中GC会在某一个时间点去回收垃圾。");
Console.ReadKey();
}
}
class Person { }
第三,关于非托管对象,如文件句柄,数据库连接等等,如何回收呢?
上面都说到GC只能回收内存中的托管对象资源,对于非托管对象例如:数据库连接,文件句柄关于很多直接和硬件打交道的资源,GC是不能涉及的
所以.Net有了IDisposable接口,IDisposable接口定义了Dispose方法,这个方法用来供程序员显式调用以释放非托管资源。使用using语句可以简化资源管理。
using(){}自动帮我们调用Dispose 方法,和try{}catch(){}finally{file.Dispose()}差不多class Program
{
static void Main(string[] args)
{
using (MyFile file = new MyFile()) {
file.OpenFile();
}
Console.ReadKey();
/*
总结:
* 非托管内存中的资源类,一般需要实现IDesposable接口
* 使用using(){},相当于try{}catch(){}finally{file.Dispose();}
* 使用了using 作用域,会自动去调用IDisposable的实现方法
* IDisposable的实现方法可以帮助调用Close的关闭方法。
*/
}
}
class MyFile : IDisposable
{
public void OpenFile(){
Console.WriteLine("打开文件!");
}
public void Dispose(){
Close();
Console.WriteLine("释放文件句柄资源!");
}
public void Close(){
Console.WriteLine("关闭文件流");
}
}
不是Dispose调用Close,而是
Close可以调用 Dispose
一般的非托管的代码。都是不是dispose来释放的。
一般有close,delete开头之类的函数用来释放的。楼主找找。
这行下面加
bp.dispose();
bp2.dispose();
GC.Collect();如果还有问题那就只能去找ocr里面有没有Dispose,close,delete神马的了。