DELPHI 串口取JPEG格式的图片
DELPHI7 + SPCOMM 控件,发送一个取图指令到串口后,串口会发送图片包过来,图片数据有头有尾,包也有固定格式,有包头,包尾。如下所示:[包头][图片开始标记][图片内容][包尾]
[包头][图片内容][包尾]
.
.
.
[包头][图片内容][包尾]
[包头][图片内容][图片结束标记][包尾]串口送过来的的数据用一个pointer标记,而且是连续的有数据过来。现在我想把接收到的图片在窗体上显示,然后可以保存在磁盘上,请问该怎么做?最好是把思路和要用到的控件名字及方法告诉我,不要一大堆的代码还没注释,看不懂。谢谢了啊……

解决方案 »

  1.   

    ?????百度和GOOGLE都只有个BOOKMARK,哥们你不是随便打的吧?
      

  2.   

    就是用SPCOMM接收啊。最主要的是,你要知道包的结构,比如你的开始包:
    [包头][图片开始标记][图片内容][包尾] 你要知道各个部所的字节数,然后定义一个结构,其他包也这样做。接收时,先建一个TMemoryStream用来存图片数据,然后通过包头判断是什么包,取相应的图片数据写入TMemoryStream中,直到收到尾包。然后Timage从流加载图片就行了
      

  3.   


    谢谢5楼的解答,我在网上找到JPEG图像的格式了,以FF D8 开始,以FF D9结束,我在接收的数据的第9位和第10位分别是 FF D8,倒数第5位和倒数第四位分别是 FF D9,找到头和尾,我现在要做的就是把 FF D8 和 FF D9 之间的数据,包括这头和尾的4个字节转换成图片存在硬盘上,再从硬盘上显示到窗体上。现在卡在了提示数据这一环上。我设了一个全局对象
    m: TMemoryStream;在TForm1.FormCreate中
    m := TMemoryStream.Create;在TForm1.Comm1ReceiveData里设一个pointer变量PP,把指向串口接收缓冲区的指针移位赋给PP
    pp:=Pointer(Integer(Buffer)+8);在TForm1.Comm1ReceiveData里设一个TJPEGImage对象photo
    photo:TJPEGImage;然后设定m的大小为3000字节(buffersize的大小在1600左右)
    m.SetSize(3000);photo:=TJPEGImage.Create;m.WriteBuffer(pp^,BufferLength-11);   {截头去尾,前面8个字节,后面3个,一共11个字节不属于图像数据}m.Position:=Integer(pp);    {这句不知道要不要}photo.LoadFromStream(m);  photo.SaveToFile('d:\1.jpg');但是运行的时候程序报错:  out of memory while expanding memory stream.
    不知道是什么原因,怎么解决,请高手指点。   
      

  4.   

    担心上面链接把网页当图片解析了,给个链接
    http://hi.csdn.net/space-4204380-do-album-picid-476599-goto-down.html这个是怎么回事啊?为什么我用自己写的程序和AccessPort发送同样的指令,返回同样的数据,就是现实格式不一样,这是什么问题啊?
      

  5.   

    楼主没有理解传输的协议问题,不管是COM与网络其它协议,只要定义了数包的格式,把他当成二进制来传输就行了。
      

  6.   

    com口传的高低电平应该都是二进制吧?这个可以接收到,没问题,关键是把这些二进制的数据变成JPEG的图片,这个有点问题
      

  7.   

    你需要研究的是如何传送任意数据流,而不是研究JPG文件的格式。
      

  8.   

    直接上代码了,高手看看这里面有没有问题,没有的话,那就是我的接收数据的串口有问题了procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
        BufferLength: Word);
    var
        m: TMemoryStream;
        photo:TJPEGImage;
        pp:Pointer;
    begin  
        m := TMemoryStream.Create;
        m.SetSize(3000);
        photo:=TJPEGImage.Create;
        
        pp:=Pointer(Integer(Buffer)+8);
        m.WriteBuffer(pp^,BufferLength-11);
        m.Position:=Integer(pp);
        
        photo.LoadFromStream(m);
        photo.SaveToFile('d:\1.jpg');    m.Free;
        photo.Free;
    end;
      

  9.   

    看到60分的贴子。回答的兴趣都没有了。算了给你个提示吧,你可以把整个图片保存到一个byte动态数组里。然后分多次发过来。
      

  10.   

    看你贴的地址图,串口应该是收到数了,不知道你的ReceiveData触发时是不是已经收完一个完整的图片数据了,看你的程序也没有判断,不知何解?有没有可能是因为你图片数据在你ReceiveData触发时还没有出现数据包的包尾,通信没有完成,此时存储的接收的数据应该不是完整的图片。不知理解对否?
      

  11.   


    我的ReceiveData触发是一接收到数据就出发,具体的过程在SPCOMM里面定义,我明天看看里面的源码,或许正是你所讲的原因,我在数据还没有接收完就对接收到的数据进行了处理,如果是这样,那应该怎么处理呢?是不是在ReceiveData开始部分加个sleep(n)?加多少合适呢?我想试下,我接收到的图片数据在1600个字节左右。有包尾,也有包头,但是由于数据包长度不定,我不知道怎么取包尾啊,以前用C好像是遍历,遍历到了就break,不然就continue,到尾还没遍历到就exit,不知 在delphi里面怎么做,请指点。另外,我看到接收到的数据包是通过AccessPort工具监视端口看到的,看到的是完整的数据包(以OD OA结尾的)。据一位比较有资历的同事介绍说,这个工具是读接收和发送缓冲区的内容来达到监控的目的,不知道是不是因为我在ReceiveData触发的时候处理的数据并不是缓冲区里面的数据,而只是一部分?另外,我用另外一个可以正常接收图片的软件和下位机通信,用AccessPort监控看到的数据和我的程序接收到的数据是一样的,但是那个程序接收到的数据时分行显示的,而我的是一行显示,不知道这个是因为什么。