DELPHI 串口取JPEG格式的图片
DELPHI7 + SPCOMM 控件,发送一个取图指令到串口后,串口会发送图片包过来,图片数据有头有尾,包也有固定格式,有包头,包尾。如下所示:[包头][图片开始标记][图片内容][包尾]
[包头][图片内容][包尾]
.
.
.
[包头][图片内容][包尾]
[包头][图片内容][图片结束标记][包尾]串口送过来的的数据用一个pointer标记,而且是连续的有数据过来。现在我想把接收到的图片在窗体上显示,然后可以保存在磁盘上,请问该怎么做?最好是把思路和要用到的控件名字及方法告诉我,不要一大堆的代码还没注释,看不懂。谢谢了啊……
DELPHI7 + SPCOMM 控件,发送一个取图指令到串口后,串口会发送图片包过来,图片数据有头有尾,包也有固定格式,有包头,包尾。如下所示:[包头][图片开始标记][图片内容][包尾]
[包头][图片内容][包尾]
.
.
.
[包头][图片内容][包尾]
[包头][图片内容][图片结束标记][包尾]串口送过来的的数据用一个pointer标记,而且是连续的有数据过来。现在我想把接收到的图片在窗体上显示,然后可以保存在磁盘上,请问该怎么做?最好是把思路和要用到的控件名字及方法告诉我,不要一大堆的代码还没注释,看不懂。谢谢了啊……
[包头][图片开始标记][图片内容][包尾] 你要知道各个部所的字节数,然后定义一个结构,其他包也这样做。接收时,先建一个TMemoryStream用来存图片数据,然后通过包头判断是什么包,取相应的图片数据写入TMemoryStream中,直到收到尾包。然后Timage从流加载图片就行了
谢谢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.
不知道是什么原因,怎么解决,请高手指点。
http://hi.csdn.net/space-4204380-do-album-picid-476599-goto-down.html这个是怎么回事啊?为什么我用自己写的程序和AccessPort发送同样的指令,返回同样的数据,就是现实格式不一样,这是什么问题啊?
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;
我的ReceiveData触发是一接收到数据就出发,具体的过程在SPCOMM里面定义,我明天看看里面的源码,或许正是你所讲的原因,我在数据还没有接收完就对接收到的数据进行了处理,如果是这样,那应该怎么处理呢?是不是在ReceiveData开始部分加个sleep(n)?加多少合适呢?我想试下,我接收到的图片数据在1600个字节左右。有包尾,也有包头,但是由于数据包长度不定,我不知道怎么取包尾啊,以前用C好像是遍历,遍历到了就break,不然就continue,到尾还没遍历到就exit,不知 在delphi里面怎么做,请指点。另外,我看到接收到的数据包是通过AccessPort工具监视端口看到的,看到的是完整的数据包(以OD OA结尾的)。据一位比较有资历的同事介绍说,这个工具是读接收和发送缓冲区的内容来达到监控的目的,不知道是不是因为我在ReceiveData触发的时候处理的数据并不是缓冲区里面的数据,而只是一部分?另外,我用另外一个可以正常接收图片的软件和下位机通信,用AccessPort监控看到的数据和我的程序接收到的数据是一样的,但是那个程序接收到的数据时分行显示的,而我的是一行显示,不知道这个是因为什么。