如何解决网络图片的传送?请教各位高人。 ( 积分: 130 )

  • 主题发起人 主题发起人 penwater191
  • 开始时间 开始时间
P

penwater191

Unregistered / Unconfirmed
GUEST, unregistred user!
程序流程:客户端点击BUTTON1后,服务器发送图片过来;

服务器端:(发送截取的屏幕图象到客户端)
procedure ScreenCap(LeftPos,TopPos,RightPos,BottomPos:integer);//截取屏幕图象
begin
bmpstream := Tmemorystream.Create;
RectWidth:=RightPos-LeftPos;
RectHeight:=BottomPos-TopPos;
SourceDC:=CreateDC('DISPLAY','','',nil);
DestDC:=CreateCompatibleDC(SourceDC);
Bhandle:=CreateCompatibleBitmap(SourceDC,RectWidth,RectHeight);
SelectObject(DestDC,Bhandle);
BitBlt(DestDC,0,0,RectWidth,RectHeight,SourceDC,LeftPos,TopPos,SRCCOPY);
Bitmap:=TBitmap.Create;
Bitmap.Handle:=BHandle;
BitMap.SaveToStream(BmpStream);
BmpStream.Position:=0;
LeftSize:=BmpStream.Size;
Bitmap.Free;
DeleteDC(DestDC);
ReleaseDC(Bhandle,SourceDC);
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf:string;
begin
if socket.ReceiveText='ft' then
begin
w:=screen.Width;
h:=screen.Height;
screencap(0,0,w,h);
Socket.SendStream(bmpstream);
end;
end;

客户端:
procedure TForm1.Button1Click(Sender: TObject);
begin
clientsocket1.Socket.SendText('ft');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;Socket: TCustomWinSocket);
var
buf:string;
begin
stream:=tmemorystream.create;
changdu:=Socket.ReceiveLength;
buf:=socket.ReceiveText;
stream.Position:=0;
stream.WriteBuffer(buf,changdu);
form1.AutoSize:=true;
form1.Align:=alclient;
image1.Stretch:=true;
image1.Align:=alclient;
image1.AutoSize:=true;
image1.Picture.Bitmap.LoadFromStream(stream);

edit1.Text:=inttostr(changdu);//写这行代码主要是为了验证是否传过来了图片

end;
 
程序流程:客户端点击BUTTON1后,服务器发送图片过来;

服务器端:(发送截取的屏幕图象到客户端)
procedure ScreenCap(LeftPos,TopPos,RightPos,BottomPos:integer);//截取屏幕图象
begin
bmpstream := Tmemorystream.Create;
RectWidth:=RightPos-LeftPos;
RectHeight:=BottomPos-TopPos;
SourceDC:=CreateDC('DISPLAY','','',nil);
DestDC:=CreateCompatibleDC(SourceDC);
Bhandle:=CreateCompatibleBitmap(SourceDC,RectWidth,RectHeight);
SelectObject(DestDC,Bhandle);
BitBlt(DestDC,0,0,RectWidth,RectHeight,SourceDC,LeftPos,TopPos,SRCCOPY);
Bitmap:=TBitmap.Create;
Bitmap.Handle:=BHandle;
BitMap.SaveToStream(BmpStream);
BmpStream.Position:=0;
LeftSize:=BmpStream.Size;
Bitmap.Free;
DeleteDC(DestDC);
ReleaseDC(Bhandle,SourceDC);
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf:string;
begin
if socket.ReceiveText='ft' then
begin
w:=screen.Width;
h:=screen.Height;
screencap(0,0,w,h);
Socket.SendStream(bmpstream);
end;
end;

客户端:
procedure TForm1.Button1Click(Sender: TObject);
begin
clientsocket1.Socket.SendText('ft');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;Socket: TCustomWinSocket);
var
buf:string;
begin
stream:=tmemorystream.create;
changdu:=Socket.ReceiveLength;
buf:=socket.ReceiveText;
stream.Position:=0;
stream.WriteBuffer(buf,changdu);
form1.AutoSize:=true;
form1.Align:=alclient;
image1.Stretch:=true;
image1.Align:=alclient;
image1.AutoSize:=true;
image1.Picture.Bitmap.LoadFromStream(stream);

edit1.Text:=inttostr(changdu);//写这行代码主要是为了验证是否传过来了图片

end;
 
服务器端图片的截取是没问题的,在本机上通过了实验;
关键是在将图片转化为数据流后,在客户端读的时候出现了问题:
并没有将传过来的图片读取显示出来;我估计是下面的代码出现了问题:请各位指教一下,问题到底出现在哪里?
stream:=tmemorystream.create;
buf:=socket.ReceiveText;
stream.WriteBuffer(buf,changdu);
image1.Picture.Bitmap.LoadFromStream(stream);
 
TBitmap.LoadFromStream 的实现如下:
procedure TBitmap.LoadFromStream(Stream: TStream);
begin
ReadStream(Stream, Stream.Size - Stream.Position);
end;
由此可知  只要在

stream.WriteBuffer(buf,changdu);
image1.Picture.Bitmap.LoadFromStream(stream);
中间加入流回位即可以了
stream.seek(0,soFromBeginning) ;
 
抓取远程屏幕图像


{抓屏幕图像,保存为内存流--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);
 
接受答案了.
 
后退
顶部