使用Httprequest从给定的URL获取图片

时间:2011-06-01 21:36:03

标签: c# performance get httprequest image

我正在尝试从网络摄像头获取图片。有一个php-python网络服务来从网络摄像头获取图片并提供服务:它提供像http://ip/jpeg/camera=1这样的图片。

private HttpWebRequest request;
private HttpWebResponse response;
private CookieContainer container;
private Uri uri;
private string _user;
private string _pass;
private string _ip;
//Login code as seen in the previous section should be here
//GetImages is meant to run as a separate thread 
private void GetImages(string camNo)
{
//create the GET request for the JPEG snapshot (found at /jpeg on the IP Camera)
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + deviceIP + "/jpeg/camera"+camNo);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = container;

//attempt to get a response from the IP110, event if error

try
{
    response = (HttpWebResponse)request.GetResponse();
}
catch (WebException e)
{
    ConnectionError(new ConnectionErrorEventArgs(e.Message));
}

//Get the stream containing the JPEG image.
Stream stream = response.GetResponseStream();

//Read the stream to memory.
byte[] buffer = new byte[100000];
int read, total = 0;

while ((read = stream.Read(buffer, total, 1000)) != 0)
{
    total += read;
}

//create a BMP image from the stream
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));

//send the bmp image to where you would like to display it. 
 }

...然后我将该位图作为jpeg存储到文件夹中。我的问题从这里开始;我想尽快完成这个过程。我想使用该代码从50个网络摄像头拍照并存储为jpeg,并且必须快速 - 我的意思是每10秒我必须从50个摄像头获取新照片。

我使用了timercontrol,并且每500ms程序给它500 ms,使用上面的代码到相机 编号并保存jpeg,但它一个接一个地工作,所以性能降低!

50ms x 500cams = 25000 ms(25sec),如果我安排定时器控制的间隔100 ms程序冻结。 当我使用上面的代码时,我在200毫秒内获得位图bmp,但是当它尝试在光盘上写为jpeg时需要很长时间。

如何更快地写入磁盘?我寻找内存映射 - 它会有帮助吗?我想将jpeg存储在光盘上,因为我将在网站上提供这些图片并与人分享。我可以使用内存映射并通过网站公开提供吗?

更新 我还使用WebClient类进行异步工作, http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=571

结果是:获得300毫秒的图片并将其写入磁盘大约700毫秒 所以我必须找到一个尽可能写入磁盘的解决方案。

哪一个更好?要将图片写入磁盘还是将图像发送到数据库? 我试图存储图片以使其准备好服务,因为在网站上人们必须看到更新的图片。成千上万的客户端查询哪一个更好?将它们存储在磁盘上还是以二进制形式存储在数据库中?

2 个答案:

答案 0 :(得分:1)

获取图像的代码是同步的。我建议您修改代码,使用HttpWebRequest.BeginGetResponse()获取图片,详见this answer

因此,当您的(单个)计时器触发时,开始向您的摄像头发出异步请求,然后(当它们完成时)将为每个已完成的请求触发回调,并且您可以保存返回的图像。

如果您需要进一步优化,则可以将图像委托保存到磁盘后台ThreadPool work item

答案 1 :(得分:0)

任何时候你需要以比堆叠响应更快的速度获得响应,你最终必须使用多个线程一次完成多项工作(最后一个字是这里的线索)。

在.NET中,这意味着要么设置自己的线程库,要么使用TPL等。

ADDED:正如下面的评论所指出的,这可能意味着使用异步调用并允许框架为您隐式创建线程,而不是自己控制它们。实际上,您可以使用线程池并仍然选择异步或同步而不控制创建的线程数。如果你真的想要了解金属,你甚至可以使用操作系统级别的中断处理程序(例如,在Ruby之前使用的一个menthod,即引入" true&#34)卸载到操作系统的线程。 ;线程而不是"绿色"线程 - 是的,TMI)。

如果您有2分钟的工作要完成并且30秒完成它,答案仍然存在,您需要一个多线程解决方案,无论您是否知道您实际上是在进行线程化(显式创建)(由框架/ OS处理的隐式创建。