前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WinCE中解决“图片采集及压缩”问题的开发历程

WinCE中解决“图片采集及压缩”问题的开发历程

作者头像
用户1170933
发布2022-05-10 14:36:27
1.2K0
发布2022-05-10 14:36:27
举报

WinCE中解决“图片采集及压缩”问题的开发历程

作者:一点一滴的Beer http://beer.cnblogs.com/

主要对解决问题的过程和方法进行介绍。

已有条件:

  • 设备:WinCE工控板一个,LCD液晶屏一个,摄像头一个,必要的接线。
  • 开发环境:开发程序的相关软件VS2005,开发SDK,工控板对应的DLL驱动

要求:

   让WinCE工控板上的摄像头拍照,然后将图片数据通过GPRS发送到指定的主机数据库中。

   GPRS发送模块是另外一个同学开发的。所以,我要做的就是拍照,并提取出图片数据,然后将数据接口给 开发GPRS的那位同学,后面要做的就不是我的事情了。

   然后这个过程就开始了,一个曲曲折折的过程啊。

第一阶段:准备用C#进行WinCE开发

    GPRS模块已经用C#开发好了,可以无线发送数据,然后就等着图片数据接口了。然后我就开始担当获取图片数据的任务了。此时,我的基础基本上是零,连WinCE到底是个什么样子的东西都不是太清楚。只知道好像很多能在XP下运行的C#函数在WinCE下都不能用了。

目前的学习资料仅限于致远公司提供的一个光盘里面的一些演示程序。

    关于摄像头的演示程序只有VS2005环境开发的,基于C++的演示程序。想变成C#都不行啊。虽然那个DLL驱动可以供C#调用,但是看那个驱动DLL的方法,在使用提取数据的那个函数的时候,必需要设置内核模式,而这个只能用C++来做,因为需要引用一个头文件中的某个函数,显然C#是没有头文件这个概念的。

    于是这个时候的计划就是,用C++来写DLL程序,将致远公司提供的硬件层的驱动再封装一遍(把那个内核模式的设置函数封装进去),然后提取出图片数据,然后再用C#调用得到图片数据,保存到一个BYTE数组中,然后通过GPRS发送。

    阶段总结:知道C#在比较底层的开发方面确实乏力,所以放弃C#转投C++。

第二阶段:用C#程序和C++的DLL产生数据交互

    用C++写的DLL可以提取到图片数据了,而且已经在工控板上的存储盘上保存了BMP位图文件。这个时候,想办法用C#主程序来承接这些数据,这个时候,就直接调用DLL中的函数,生成文件,然后此函数返回文件路径,C#程序中得到了文件路径,然后再读取文件,然后GPRS发送位图数据流。

阶段总结:用上面的方案虽然可以达到目标,但是还存在如下巨大缺陷。

缺点:

  1. 1. 此时提取的图片数据为150K的RGB565编码方式的位图文件,发送一次,耗的时间太长了,而且耗流量。每拍一次图片就要往存储盘里面写一次文件,长期下来,反复擦写存储盘,必然会带来硬件的快速损耗。
  2. 2. 每拍一次图片就要往存储盘里面写一次文件,长期下来,反复擦写存储盘,必然会带来硬件的快速损耗。

要求:

1. 对图片进行压缩,最好是用JPEG格式的。

2. 将图片的处理都放在内存中处理,最后也是在内存中将数据流传递给C#主程序。

第三阶段:压缩BMP图片到JPEG图片

    在XP下用C#可以直接读BMP文件,然后构造一个Bitmap类,然后有个成员函数,直接一步保存为你想要的格式,比如保存成JPG,可以从150K压缩到10K,而且人眼基本看不出差别。本来以为可以很快搞定的,结果发现,同样的代码在XP环境下可以运行,在WinCE平台下就不行了。花了几天做了好多好多的试验,才最后完全确实,这种方法走不通。将XP环境下的位图文件和代码全部复制到开发板中,但是就是不能得到和XP下同样的运行结果,在程序读取文件并构造位图对象的时候,在WinCE下位出现异常。可能是因为WinCE和WinXP下的.NET框架类的数据结构不太一样吧。这个很沮丧啊。一下不知道怎么办了。

    然后研究致远公司提供的代码示例,了解BMP位图的文件结构,从存储内容上进行分析。想从最底层上对图片进行逐字节的运算和操作。但是后来想到Jpeg的压缩算法实在太复杂,最好是有现有的类函数提供编码解码压缩。

    最后到网上找到一篇关于WinCE下的BMP转JPG的文章,用的是IImage,IImageFactory接口。但是网上谈到这种转码压缩方法的时候,都是说RGB555的可以,但是RGB565的不行。刚好我的图片就是RGB565的,我不信,然后将网上给的代码放到程序中试验,结果果然不行,很泄气。想找个RGB555的图片,但是找不到,网上都说用Photoshop可以生成,我也没有搞成功。后来在胡博士的提示下:RGB565和RGB555编码方式可以通过数据位运算进行转换,转换成功后,再用IImage试试。后来我参考网上下载的一篇关于BMP位图文件结构的文档,然后对RGB565成功转码成RGB555的位图文件。然后很顺利,RGB555可以用IImageFactory转码成jpg格式。150K的位图可以压缩到10K。

第三阶段:在内存中实现图片压缩

    在IImageFactory中,有个函数,可以直接将jpg的编码结果保存在IStream流中,当时自己很高兴,有个这现成的函数,但后来发现,数据根本就就没有保存进去。然后又开始了对IStream的使用方法进行研究,发现,经过那个函数后,IStream的大小变成了图片的大小 ,但是却读不出数据,我以为是因为ISream作为传出参数,但是不是传的指针的地址,可能有问题。后来又是在胡博士的提醒下,原来是因为我的ISream在赋值完毕后,没有将偏移指针移到首位,导致后面没有成功读出数据。这个时候才知道,原来ISream只是一个接口类,也就是所谓的虚类,必需要和一个内存进行绑定或者进行一次实例化。属于比较特殊的指针,在作为传出参数使用的时候,不需要使用指针的地址作为传出参数就可以达到传出数据的功能。

第四阶段:在C#主程序中对DLL数据进行承接

    因为最终我要做出的效果就是,能够在C#程序中提供一个数据接口,也就是我能够给GPRS模块一个在C#环境下的byte数组。这个时候又遇到一点小麻烦问题了,就是在C++中有指针和动态内存分配,但是在C#里面“好像”没有。这个时候又遇到麻烦了。网上普遍说的,C++的DLL向C#传出字符数组char*时,在C#程序中对应的数据类型是StringBuilder类。当时看到这个觉得比较高兴,也在XP环境下测试成功,主要就是一个引用DLL的时候,设置一个传值的编码方式,一般默认为UniCode,改成Ansi就可以了。

    以为可以直接往WinCE下移植了,但是移植的时候,发现WinCE下的C#调用DLL的时候,设置传值编码方式的选项中,没有Ansi选项,于是这就表示不能使用StringBuilder来进行数据承接了,否则承接也是乱码。

    最后到网上找到了一个C#中的一个可以“模拟”指针的方法IntPtr,可以实现非托管内存数据和托管内存数据之间的读取的转换,也就是所谓的内存操作。这个可以和C++中的动态分配内存相对应起来。于是这个技术问题解决后,BMP转JPG才算在技术上完全走通了。

     从2010-10-1号开始,一直做到现在2010-11-5,终于算是完工了。感觉搞研发真的好难啊,特别是你在没有任何基础的时候开始,本来你有个大致思路,可以分成一、二、三步,但是其实你自己都不知道每一步在实现的过程中会遇到什么问题,或者甚至你都不知道,你解决了第一个问题后,会不会在第二个问题那个地方卡住而无法走下去。这次我就是这样,好几次都差点放弃了,很多时候看不到任何解决问题的希望。但是还好,旁边有几位大神在关键时刻点拨一下,立刻就感觉有个方向了,然后就把问题解决了。冥思苦想终可得的喜悦真的是无法比拟的,呵呵,想想人生也是如此吧,很多时候,你都看不到明天是什么,很多时候,你都会绝望得想放弃,但是坚持一会,多尝试,不要怕失败,失败也是一种经验,在你实在坚持不下去了,可以向你身边的朋友老师求助,他们会给你提一些意见和建议的,很多情况下也许是他们的某一句不经意的意见,可以在你的失败的经验上进行神来一笔,然后你问题就一下迎刃而解了,比如我三次遇到瓶颈,然后请教同实验室的胡博士,博士根据他的经验提出了一些他认为的可能问题,于是我参照自身的实验失败经验和教训,往往立刻就把问题解决了。

      解决问题的时候,就是一个先不断地对已知的方法进行尝试,然后不断地否定旧方法,再不断学习新方法,再一个个否定,到最后才终于把问题解决的过程,总是很曲折的,就看你能不能坚持下去直到反它解决了。

写下这个心得,告诫自己:虽然你无法估计问题有多难,但千万不要轻易放弃,因为有可能希望就在前方,还坚持一会就行了,当你排除一切障碍终于将路走通后,再看看以前那些问题,感觉都不再是问题了,而这个时候,你所获利的不仅仅是“成功解决某个问题”的结果,而是解决问题的方法和步骤以及遇到麻烦时应对的心境了。相信最后的心情就像苏轼所说的那样“回首向来萧瑟处,归去,也无风雨也无晴”。

 后面将再发系列技术贴,对各个步骤的的技术进行详细介绍。

------------------------------------------------------------------

Author:一点一滴的Beer

Email /Gtalk:dreamzsm@gmail.com

From:http://www.cnblogs.com/beer

Notes:欢迎转贴,但请在页面中加个链接注明出处

Time:2010-11-16 in Whu

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档