IdUdpClient抓屏使用Memorystream出错请教(Jpeg Error #53)(50分)

  • 主题发起人 主题发起人 sxdthonda
  • 开始时间 开始时间
可以用流来发送 比如发送的东西存在流sendstream中
在发送时这样弄
sendstream.postion:=0;
idudpclient1.sendbuffer(sendstream.memory^,sendstream.size);
我的毕业设计里是这样做的 是没有错的
 
下面是我写的发送图片的代码,调试了的没有错


form1.zhuaping;//我自己写的抓取图片的函数
form1.yasuotupian;//自己写的压缩抓取图片的函数
//102表明发送的是图片的总共大小
bmpsize:=bmpstream.Size;
ctrlcode:=102;
sendstream.WriteBuffer(ctrlcode,sizeof(ctrlcode)); //写入命令
sendstream.WriteBuffer(bmpsize,sizeof(bmpsize));//写入压缩后图片的大小
sendstream.Position :=0;
sendsize:=sendstream.size;
idudpclient1.SendBuffer(sendstream.memory^,sendsize);
sendstream.Clear ;



//上面发送了图片的大小,接下来发送压缩了的图片
leftsize:=bmpsize;
while leftsize>0 do
begin
sendstream.WriteBuffer(index,4);
ctrlcode:=103; // 103表示 发送的 是图片
sendstream.Write(ctrlcode,sizeof(ctrlcode));//写入被控机的命令
if leftsize> (bufsize-sizeof(ctrlcode)) then
readsize:=bufsize-sizeof(ctrlcode)-1000//在发送的的时候 发送的内容大小与idudpclient的buffersize一样大的话 好象容易出错 所以我减了1000
else
readsize:=leftsize;//readsize是要写入发送流的数据的大小
leftsize:=leftsize-readsize;//还没发送的数据的大小

sendstream.CopyFrom(bmpstream,readsize);


sendstream.Position :=0;
sendsize:=sendstream.size;
idudpclient1.SendBuffer(sendstream.memory^,sendsize);

sendstream.Clear ;
end;
bmpstream.Clear ;


下面是接收方的一些处理 在idudpserver的onread 中
recestream.loadfrom(adata);
recestream.readbuffer(ctrlcode,4);
case ctrlcode of
102:begin //102表明被控机发过来被压缩后的图片大小
recestream.ReadBuffer(bmpsize,sizeof(Fbmpsize));
bmpstream.clear;//bmpstream用来接收发过来的图片
end;
103:begin//接收图片 bmpstream用来接受发送过来压缩了的图片
bmpstream.CopyFrom(Fms,Fms.Size-4);
if bmpstream.Size=Fbmpsize then
jieya;//自己写的解压图片的函数

end;
 
远程控制篇:抓取远程屏幕图像

{抓屏幕图像,保存为内存流--BMP流,压缩BMP流,JPG流,以及使用流}
{在网络中传送BMP流和JPG流的速度没测试过}
{BMP流的压缩是无损压缩}
{
全局变量
memoryStream:TMemoryStream;
memoryStream:=TMemoryStream.create;
}

var
image:Timage;
jpgstream:TJPEGImage;
ss:tcanvas;

begin
ss:=tcanvas.Create;
ss.Handle:=getdc(0);
image:=timage.Create(self);
image.width:=Screen.width;
image.Height:=screen.Height ;
image.picture.bitmap.PixelFormat:= pf16bit;
bitblt(image.canvas.handle,0,0,image.width,image.height,ss.handle,0,0,srccopy);

{大大的原始BMP流
image.picture.bitmap.SaveToStream(memoryStream);
}

{无损压缩BMP流 uses Zlib.pas
{先定义变量count,DestStream,SourceStream}
image.picture.bitmap.SaveToStream(memoryStream);
Count:=memoryStream.Size;
DestStream:=TMemoryStream.Create;
{压缩方式:clnone,clfastest,cldefault,clmax}
SourceStream:=TCompressionStream.Create(cldefault, DestStream);
try
memoryStream.SaveToStream(SourceStream);
SourceStream.Free;
memoryStream.Clear;
memoryStream.WriteBuffer(Count, SizeOf(Count));
memoryStream.CopyFrom(DestStream, 0);
finally
DestStream.Free;
end;
}

{JPG流 uses jpeg
jpgstream:= TJPEGImage.Create;
jpgstream.Assign(image.picture.bitmap);
jpgstream.CompressionQuality:=50; {压缩质量}
jpgstream.Compress;
jpgstream.SaveToStream(memoryStream);{保存为JPG流}
jpgstream.free;
}

ReleaseDC(0,ss.Handle);
image.free;

{发送内存流...}

-----------------------------------------------------
{接收内存流...}

{使用BMP流
image.Picture.Bitmap.LoadFromStream(bmpStream);}

{还原压缩的BMP流 uses:Zlib.pas
先定义变量count,buffer,DestStream,SourceStream
memoryStream是压缩的BMP流
memoryStream.ReadBuffer(Count, SizeOf(Count));
GetMem(Buffer, Count);
DestStream:=TMemoryStream.Create;
SourceStream:=TDecompressionStream.Create(memoryStream);
Try
SourceStream.ReadBuffer(Buffer^, Count);
DestStream.WriteBuffer(Buffer^, Count);
DestStream.Position:=0;
image.Picture.Bitmap.LoadFromStream(DestStream);
finally
FreeMem(Buffer);
DestStream.Free;
end;
}

使用JPG流 image.Picture.Assign(jpgstream);
 
andd_chen兄是指抓到指定硬盘的文件问题吗?

我也考虑了这个,程序还没有最终完工,在指定硬盘保存时我准备参考DVR的功能,循环存放,检查硬盘剩余大小,然后自动清空最早的文件。

如果有别的问题,请指教。 呵,多谢大家的帮助。
 
后退
顶部