Delphi XE的IDE有个Bug,因此IdUDPServer控件及OnUDPRead事件只好在运行时生成。请不要见怪。我是想通过UDP将Img1中修改的部分发送到服务端,并重画在Img2上。现在能做的是,可以获得需要发送的最小矩形,使用SendBuffer命令以TMemoryStream方式将其划分成最大1024个字节大小进行发送。客户端以'_STARTIMG_'为表示开始,‘_END__IMG_'表示发送结束;服务端接收到“_STARTIMG_”之后开始接收数据,每次直接通过MemRec.Write(Adata, size)写入全局变量MemRec(TMemoryStream)。当服务端收到‘_END__IMG_'之后结束结果,将MemRec内容画到IMG2上。现在,的问题是MemRec无法画到IMG2上,而MemOld则可以。但通过CompareMem命令发现,两者的内容是相同的。这一点实在就想不通了。由于这是一个还没理清头绪的程序,我的表述可能很不清楚。如有需要,请跟贴,我再做详细说明。
//发送程序
procedure TForm1.btn1Click(Sender: TObject);
var
mem: TMemoryStream;
Buf: array [0..1023] of Char;
pos, len: Integer;
RecStr: String;
TmpImg1, TmpImg2: TImage;
BitBuf: TBytes;
begin
RectNew.Top:=0; RectNew.Left:=0;
RectNew.Bottom:=rect.Bottom-rect.Top;
RectNew.Right:=rect.Right-rect.Left;
form1.Caption:=''; mem:= TMemoryStream.Create;
TmpImg1:=TImage.Create(self);
TmpImg1.Picture.Bitmap.Width:=RectNew.Right;
TmpImg1.Picture.Bitmap.Height:=RectNew.Bottom; TmpImg1.Canvas.CopyRect(RectNew, img1.Canvas, rect);
TmpImg1.Picture.Bitmap.SaveToStream(mem); MemOld.Free;
MemOld:=TMemoryStream.Create;
TmpImg2:=TImage.Create(self);
TmpImg1.Picture.Bitmap.SaveToStream(MemOld); //mem 和 MemOld的内容均正确// MemOld.Position:=0; //通过下面三句可以把画正确地画到IMG2中
// TmpImg2.Picture.Bitmap.LoadFromStream(MemOld); //为了与传输结果比较,此处的MemOld为一全局变量
// img2.Canvas.CopyRect(rect, TmpImg2.Canvas, rectnew); if mem.Size>0 then begin
idpclnt1.Send('_STARTIMG_');
pos:=0;
while pos<mem.Size do begin
len:=1024;
if mem.Size-pos<1024 then len:=mem.Size-pos;
mem.Read(buf, len);
SetLength(BitBuf, len);
Move(buf[1], BitBuf[0], Len);
idpclnt1.SendBuffer(BitBuf);
inc(pos, len);
end;
idpclnt1.Send('_END__IMG_');
end; Form1.Caption:=Form1.Caption+' end';
mem.Free;
TmpImg1.Free;
TmpImg2.Free;
end;//接收程序
procedure Tform1.UDPRead(AThread: TIdUDPListenerThread; AData: TArray<Byte>; ABinding: TIdSocketHandle);
var
str, str1, str2: string;
size, i, flag: Integer;
tmp: TImage;
NewRect: TRect;
just: Boolean;
begin
NewRect.Top:=0;
NewRect.Left:=0;
NewRect.Bottom:=rect.Bottom-rect.Top;
NewRect.Right:=rect.Right-rect.Left; Flag:=1;
Size:=Length(AData);
if size=10 then begin
SetLength(str, 10);
for i := 1 to 10 do str[i]:=Char(AData[i-1]);
if str='_STARTIMG_' then begin
flag:=0;
form1.Tag:=1;
end;
if str='_END__IMG_' then begin
flag:=2;
form1.Tag:=0;
end;
end; case flag of
0: begin
form1.Caption:=Form1.Caption+'S_';
MemRec:=TMemoryStream.Create;
form1.Caption:=Form1.Caption+'S_';
end;
2: begin
form1.Caption:=Form1.Caption+'_E';
tmp:=TImage.Create(self);
try
MemRec.Position:=0;
Form1.mmo1.Lines.Add(IntToStr(MemRec.Size)+ ' '+inttostr(MemOld.Size)) ; MemOld.Position:=0; //用MemOld可以正确地将需要的部分画到IMG2中
tmp.Picture.Bitmap.LoadFromStream(MemOld);
img2.Canvas.CopyRect(rect, tmp.Canvas, NewRect);// MemRec.Position:=0; //用MemRec 不能 需要的部分画到IMG2中
// tmp.Picture.Bitmap.LoadFromStream(MemRec);
// img2.Canvas.CopyRect(rect, tmp.Canvas, NewRect); just:=CompareMem(MemRec.Memory,MemOld.Memory, MemOld.Size); //但内存比较的结果是MemOld与MemRec的内容完全相同 if just then form1.mmo1.Lines.Add(IntToStr(1))
else form1.mmo1.Lines.Add(IntToStr(0));
finally
tmp.Free;
MemRec.Free;
end;
form1.img2.Canvas.MoveTo(0, 0);
form1.img2.Canvas.LineTo(30, 30);
end;
1: if form1.tag=1 then begin
MemRec.Write(Adata, size);
form1.Caption:=Form1.Caption+' - '+inttostr(MemRec.Size);
end;
end;end;
//发送程序
procedure TForm1.btn1Click(Sender: TObject);
var
mem: TMemoryStream;
Buf: array [0..1023] of Char;
pos, len: Integer;
RecStr: String;
TmpImg1, TmpImg2: TImage;
BitBuf: TBytes;
begin
RectNew.Top:=0; RectNew.Left:=0;
RectNew.Bottom:=rect.Bottom-rect.Top;
RectNew.Right:=rect.Right-rect.Left;
form1.Caption:=''; mem:= TMemoryStream.Create;
TmpImg1:=TImage.Create(self);
TmpImg1.Picture.Bitmap.Width:=RectNew.Right;
TmpImg1.Picture.Bitmap.Height:=RectNew.Bottom; TmpImg1.Canvas.CopyRect(RectNew, img1.Canvas, rect);
TmpImg1.Picture.Bitmap.SaveToStream(mem); MemOld.Free;
MemOld:=TMemoryStream.Create;
TmpImg2:=TImage.Create(self);
TmpImg1.Picture.Bitmap.SaveToStream(MemOld); //mem 和 MemOld的内容均正确// MemOld.Position:=0; //通过下面三句可以把画正确地画到IMG2中
// TmpImg2.Picture.Bitmap.LoadFromStream(MemOld); //为了与传输结果比较,此处的MemOld为一全局变量
// img2.Canvas.CopyRect(rect, TmpImg2.Canvas, rectnew); if mem.Size>0 then begin
idpclnt1.Send('_STARTIMG_');
pos:=0;
while pos<mem.Size do begin
len:=1024;
if mem.Size-pos<1024 then len:=mem.Size-pos;
mem.Read(buf, len);
SetLength(BitBuf, len);
Move(buf[1], BitBuf[0], Len);
idpclnt1.SendBuffer(BitBuf);
inc(pos, len);
end;
idpclnt1.Send('_END__IMG_');
end; Form1.Caption:=Form1.Caption+' end';
mem.Free;
TmpImg1.Free;
TmpImg2.Free;
end;//接收程序
procedure Tform1.UDPRead(AThread: TIdUDPListenerThread; AData: TArray<Byte>; ABinding: TIdSocketHandle);
var
str, str1, str2: string;
size, i, flag: Integer;
tmp: TImage;
NewRect: TRect;
just: Boolean;
begin
NewRect.Top:=0;
NewRect.Left:=0;
NewRect.Bottom:=rect.Bottom-rect.Top;
NewRect.Right:=rect.Right-rect.Left; Flag:=1;
Size:=Length(AData);
if size=10 then begin
SetLength(str, 10);
for i := 1 to 10 do str[i]:=Char(AData[i-1]);
if str='_STARTIMG_' then begin
flag:=0;
form1.Tag:=1;
end;
if str='_END__IMG_' then begin
flag:=2;
form1.Tag:=0;
end;
end; case flag of
0: begin
form1.Caption:=Form1.Caption+'S_';
MemRec:=TMemoryStream.Create;
form1.Caption:=Form1.Caption+'S_';
end;
2: begin
form1.Caption:=Form1.Caption+'_E';
tmp:=TImage.Create(self);
try
MemRec.Position:=0;
Form1.mmo1.Lines.Add(IntToStr(MemRec.Size)+ ' '+inttostr(MemOld.Size)) ; MemOld.Position:=0; //用MemOld可以正确地将需要的部分画到IMG2中
tmp.Picture.Bitmap.LoadFromStream(MemOld);
img2.Canvas.CopyRect(rect, tmp.Canvas, NewRect);// MemRec.Position:=0; //用MemRec 不能 需要的部分画到IMG2中
// tmp.Picture.Bitmap.LoadFromStream(MemRec);
// img2.Canvas.CopyRect(rect, tmp.Canvas, NewRect); just:=CompareMem(MemRec.Memory,MemOld.Memory, MemOld.Size); //但内存比较的结果是MemOld与MemRec的内容完全相同 if just then form1.mmo1.Lines.Add(IntToStr(1))
else form1.mmo1.Lines.Add(IntToStr(0));
finally
tmp.Free;
MemRec.Free;
end;
form1.img2.Canvas.MoveTo(0, 0);
form1.img2.Canvas.LineTo(30, 30);
end;
1: if form1.tag=1 then begin
MemRec.Write(Adata, size);
form1.Caption:=Form1.Caption+' - '+inttostr(MemRec.Size);
end;
end;end;
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货