winFrom 抓取屏幕指定区域 代码运行15分钟左右就出现(缓冲操作当前正在进行中,无法释放 BufferedGraphicsContext) 本帖最后由 matrixyz 于 2015-03-02 16:49:27 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 imgGraphics.CopyFromScreen(x, y, 0, 0, new Size(w, h)); imgGraphics.Dispose(); 《--这句应放在finally里面而不是放在try里。 if (graphicsCount > 1000)//执行1000次后强制GC回收 { GC.Collect(); graphicsCount = 0; } 这里应放在image_s.Dispose(); 之后。void getTargetPicTypeA(int x, int y, int w, int h) { //创建图象,保存将来截取的图象 Bitmap image_s = new Bitmap(w, h); Graphics imgGraphics = Graphics.FromImage(image_s); try { imgGraphics.CopyFromScreen(x, y, 0, 0, new Size(w, h)); graphicsCount = graphicsCount + 1; } catch (Exception e) { exception += e.ToString() + "\r\n"; } imgGraphics.Dispose(); image_s.Dispose(); if (graphicsCount > 1000)//执行1000次后强制GC回收 { GC.Collect(); graphicsCount = 0; } } 既然如此频繁 你应该考虑把imgGraphics和image_s缓存起来 不要200毫秒创建一次 本拉登兄的 提示试过了,还是没有改善,不过还是thank you 贴上完整代码,请高手赐教啊,在线等... void executeTask()//该方法每200毫秒调用一次 {//这个图片 大小为 260 * 80 Bitmap bmp = getTargetPicTypeA(dataWin_x, dataWin_y, dataWin_w, dataWin_h); //以下为用指针法扫描图片,判断每个像素 BitmapData bData = bmp.LockBits(new Rectangle(0, 0, dataWin_w, dataWin_h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); unsafe { string colors = ""; int count_cell_pos = 0; foreach (int[] posi in allCharTables) { for (int i = y1; i < y2; i++) { int lineKey = 0; for (int j = x1; j < x2; j++) { byte* color = (byte*)bData.Scan0 + j * 3 + i * bData.Stride; int colorValue = (*(color + 2) + *(color + 1) + *color); if (colorValue > 25) { //其他任务..... //分析 图片上的文本并存储到数组 } } } } bmp.UnlockBits(bData); bmp.Dispose(); graphicsCount = graphicsCount + 1; if (graphicsCount > 1000) { GC.Collect(); graphicsCount = 0; tbx_exception_list.Text = tbx_exception_list.Text + "@@@@@@@@" + graphicsCount.ToString() + "@@@@@@@@@@@@"; } } Bitmap getTargetPicTypeA(int x, int y, int w, int h) { //创建图象,保存将来截取的图象 Bitmap image_s = new Bitmap(w, h); Graphics imgGraphics = Graphics.FromImage(image_s); try { imgGraphics.CopyFromScreen(x, y, 0, 0, new Size(w, h)); imgGraphics.Dispose(); } catch (Exception e) { exception += e.ToString() + "\r\n"; } finally { imgGraphics.Dispose(); } return image_s; } private void Foo() { using (Bitmap bmp = (Bitmap)Form1.GetImageFromScreen(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)) { BitmapData bmpData = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); byte[] byColor = new byte[bmpData.Height * bmpData.Stride]; Marshal.Copy(bmpData.Scan0, byColor, 0, byColor.Length); int index = 0; int v = 0; for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { index = y * bmpData.Stride + x * 3; v = byColor[index] + byColor[index + 1] + byColor[index + 2]; if (v > 25) { //do something... } } } //bmp.UnlockBits(bmpData); }}private static Image GetImageFromScreen(int x, int y, int width, int height) { Bitmap bmp = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(bmp)) { g.CopyFromScreen(x, y, 0, 0, bmp.Size); } return bmp;}我自己按照你的逻辑写的 没有什么问题 那估计就看你其他代码问题了比如:你确定你的那个foreach(var posi in allCharTables) 是需要的? 你的代码里面没有看到用还有 你timer 200毫秒执行一次 如果在这期间 你执行一次所需要的时间都不止200毫秒呢?如我上面Foo() 而且你里面遍历像素外面还有一个foreach里面还有其他逻辑判断 你看看 你的那个方法 能在200毫秒内执行完? 窗体的主线程在最小化或隐藏后是否运行 类属性只读属性的修改问题 高分秒结贴!DataTable行排序问题! 高手指点:设置这么一种情况,任务栏中有两个窗口,点击其中一个另一个跟着显示在旁边,或者一块最小化或最大化,如何实现? web下载文件的锁定是怎样做的? 【求助】如果禁用USB存储设备读出权限 简单:注册表更改和锁定的问题 请问:怎样往IE里添加自定义的工具条(像Google Toolbar,MSN Toolbar那样的)? 写过GPS GT06协议的进来帮个忙。 WebService.htc的问题。 c#中如何使用ffmpeg实现视频截图 关于一个数据库显示到UI的问题
imgGraphics.Dispose(); 《--这句应放在finally里面而不是放在try里。
if (graphicsCount > 1000)//执行1000次后强制GC回收
{
GC.Collect();
graphicsCount = 0;
}
这里应放在image_s.Dispose(); 之后。
void getTargetPicTypeA(int x, int y, int w, int h)
{
//创建图象,保存将来截取的图象
Bitmap image_s = new Bitmap(w, h);
Graphics imgGraphics = Graphics.FromImage(image_s);
try
{
imgGraphics.CopyFromScreen(x, y, 0, 0, new Size(w, h));
graphicsCount = graphicsCount + 1;
}
catch (Exception e)
{
exception += e.ToString() + "\r\n";
}
imgGraphics.Dispose();
image_s.Dispose();
if (graphicsCount > 1000)//执行1000次后强制GC回收
{
GC.Collect();
graphicsCount = 0;
}
}
void executeTask()//该方法每200毫秒调用一次
{//这个图片 大小为 260 * 80
Bitmap bmp = getTargetPicTypeA(dataWin_x, dataWin_y, dataWin_w, dataWin_h);
//以下为用指针法扫描图片,判断每个像素
BitmapData bData = bmp.LockBits(new Rectangle(0, 0, dataWin_w, dataWin_h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
unsafe
{
string colors = "";
int count_cell_pos = 0;
foreach (int[] posi in allCharTables)
{
for (int i = y1; i < y2; i++)
{
int lineKey = 0;
for (int j = x1; j < x2; j++)
{
byte* color = (byte*)bData.Scan0 + j * 3 + i * bData.Stride;
int colorValue = (*(color + 2) + *(color + 1) + *color);
if (colorValue > 25)
{
//其他任务.....
//分析 图片上的文本并存储到数组
}
}
}
}
bmp.UnlockBits(bData);
bmp.Dispose(); graphicsCount = graphicsCount + 1;
if (graphicsCount > 1000)
{
GC.Collect();
graphicsCount = 0;
tbx_exception_list.Text = tbx_exception_list.Text + "@@@@@@@@" + graphicsCount.ToString() + "@@@@@@@@@@@@";
}
} Bitmap getTargetPicTypeA(int x, int y, int w, int h)
{
//创建图象,保存将来截取的图象
Bitmap image_s = new Bitmap(w, h);
Graphics imgGraphics = Graphics.FromImage(image_s);
try
{
imgGraphics.CopyFromScreen(x, y, 0, 0, new Size(w, h));
imgGraphics.Dispose();
}
catch (Exception e)
{ exception += e.ToString() + "\r\n";
}
finally {
imgGraphics.Dispose();
} return image_s;
}
private void Foo() {
using (Bitmap bmp = (Bitmap)Form1.GetImageFromScreen(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)) {
BitmapData bmpData = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte[] byColor = new byte[bmpData.Height * bmpData.Stride];
Marshal.Copy(bmpData.Scan0, byColor, 0, byColor.Length);
int index = 0;
int v = 0;
for (int y = 0; y < bmp.Height; y++) {
for (int x = 0; x < bmp.Width; x++) {
index = y * bmpData.Stride + x * 3;
v = byColor[index] + byColor[index + 1] + byColor[index + 2];
if (v > 25) {
//do something...
}
}
}
//bmp.UnlockBits(bmpData);
}
}private static Image GetImageFromScreen(int x, int y, int width, int height) {
Bitmap bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp)) {
g.CopyFromScreen(x, y, 0, 0, bmp.Size);
}
return bmp;
}我自己按照你的逻辑写的 没有什么问题 那估计就看你其他代码问题了
比如:
你确定你的那个foreach(var posi in allCharTables) 是需要的? 你的代码里面没有看到用
还有 你timer 200毫秒执行一次 如果在这期间 你执行一次所需要的时间都不止200毫秒呢?如我上面Foo() 而且你里面遍历像素外面还有一个foreach里面还有其他逻辑判断 你看看 你的那个方法 能在200毫秒内执行完?