又是三天,socket下载图片的问题总算搞定了
不知不觉,三天的时间又过去了。这三天只做了一件事,那就是解决用socket下载图片并显示的问题。
最初连怎么在SDK显示JPG/GIF图片的方法也不知道,只有不停的百度,不停的Google,本来以为这个问题比前两天MD5的问题简单,因为网上应该有现成的资料,但却硬是花了我整整三天的时间。不知是我找资料的能力有问题,还是基础知识实在太差,MSDN的强大功能又基本不会用。
本来连我自己都认为这是一个简单的问题,用socket下载图片很简单,发送一个报文然后用recv函数就能接收图片数据了,问题的关键是我不知道怎么将接收的图片数据显示出来。
今天晚上终于把这个问题解决了,其实真的很简单,关键代码还不到10行。就是先将recv函数接收HTTP头给去掉,保留数据正文部分。然后用GDI+来读取图片数据,最后用Image类来将图片画到窗体上。
具体的实现方法改天再细细的拟一遍,先说说这几天遇到的一些问题。
我的目的是从网上下载图片,将图片数据放在缓冲区,然后直接在程序中显示出来。但首先需要知道图片数据是recv函数返回数据中的哪些内容,于是开始测试图片下载并保存到文件的功能,因为只要保存的图片文件能正常显示,那就能确定存入缓冲区的图片数据了。但测试这个功能却花了我三天的时间,本来在网上找了个现成的代码,但下载保存的图片文件怎么也显示不出来。还好,今晚又找了个程序,总算搞定了图片下载并保存到文件的功能,结果非常郁闷,原来在新建图片文件进行写入时,没有设置为二进制模式写入,看看这句花了我两天时间的代码,严格的说,不是一句,而仅仅只是一个字符:
fp = fopen("a.gif","wb");
Oh!My God!就因为少了个“b”。
到此已经知道保留recv函数返回数据中的哪些内容,接下来就是将这些内容直接显示出来。
于是又是一翻百度和Google,在CSDN上看到了个贴子,贴子中提示用GDI+来显示图片,但没说具体的实现方法。找了半天,找了几句关键性的代码:
- IStream* istream;
- HGLOBAL m_hGlobal = GlobalAlloc(GPTR, len); //lpBITs是内存中图象数据, len是它的长度
- VOID* global_addr = GlobalLock(m_hGlobal);
- memcpy(global_addr,lPBits, len);
- CreateStreamOnHGlobal(m_hGlobal,true, &istream );
- bitmap = new BITmap(istream,false);
- //然后画到dialog上
到这里,其实在心里已经有了个大概的思路,但程序需要自己调试。起初测试了保存图片到文件的功能,没有问题,保存的图片能正常显示,但在用GDI+显示时却卡了壳,怎么也显示不了,最后发现是自己函数设计的问题,处理后的图片数据没有传出来。
知道具体的实现方法,以后的事情就好办了,不过仍然有些小问题。
比如用socket下载图片时,recv函数返回的数据怎么赋值给其它变量,我用strcpy函数来复制,发现数据会丢失,我想用memcpy函数应该能解决这个问题。
不用说,这篇笔记写得绝对的乱,为了解决这个问题,曾一度想咂键盘,工作又忙,连做梦都梦到程序进入死循环,怎么也跳不出来,呵呵~好多年没有这样的感觉了。
明天需要再改改代码,今晚虽然把功能实现了,但仍有不少小问题需要解决。