我正在做一个远程控制软件, 想把整个屏幕取下来并把它分为8*8个区块,以下是个完整的线程, 如果去掉分区块的部分代码, 速度可达每秒取屏80幅, 加上后速度降低到每两秒1幅. 分析得到, 从一个图像的区块拷贝到回一图像花费大量的时间, 各位有什么好的办法解决?unit Unit_Clt_CopyScrThread;interfaceuses
Windows,SysUtils,Classes,Forms,Graphics;type
TCopyScrThread = class(TThread)
private
DemoFullBmp: TBitmap; // 整屏图像
SplitedBmp: TBitmap; // 块区临时图像 procedure CopyScreen; // 取整屏图像保存在DemoFullBmp
procedure SplitBmp2Streams; // 把整屏图像分为8*8个区块, 保存在DemoStreams
protected
procedure DoTerminate;override;
procedure Execute; override;
public
constructor Create(Suspended:Boolean);
destructor Destroy(); override;
end;implementation
var
DemoStreams:array[0..63] of TMemoryStream; //保存获取的8*8个区图像流constructor TCopyScrThread.Create(Suspended:Boolean);
var
i: integer;
begin
inherited Create(Suspended);
FreeOnTerminate := true; DemoFullBmp := TBitmap.Create; SplitedBmp := TBitmap.Create;
SplitedBmp.PixelFormat := pf15bit; for i:=0 to 63 do
DemoStreams[i] := TMemoryStream.Create;
end;destructor TCopyScrThread.Destroy();
var
i: integer;
begin
inherited Destroy;
DemoFullBmp.Free;
SplitedBmp.Free;
for i:=0 to 63 do
DemoStreams[i].Free;
end;procedure TCopyScrThread.DoTerminate;
begin
inherited DoTerminate;
end;procedure TCopyScrThread.Execute;
begin
while not Terminated and not Suspended do
begin
Synchronize(CopyScreen);
Application.ProcessMessages;
Synchronize(SplitBmp2Streams);
Application.ProcessMessages;
end;
end;procedure TCopyScrThread.CopyScreen;
var
hCursor:integer;
ptCursor:TPoint;
icoCursor:TIcon;
iconInfoCursor:TIconInfo;
intThreadld: dword; hScreen:integer;
dcScreen:integer;
rectScreen:TRect;
begin
hScreen := GetDesktopWindow();
dcScreen := GetDC(hScreen); Application.ProcessMessages; GetWindowRect(hScreen, rectScreen);
DemoFullBmp.Width := rectScreen.Right-rectScreen.Left;
DemoFullBmp.Height := rectScreen.Bottom-rectScreen.Top;
BitBlt(DemoFullBmp.Canvas.Handle, 0, 0, DemoFullBmp.Width, DemoFullBmp.Height, dcScreen, 0, 0, SRCCOPY);
Application.ProcessMessages; ReleaseDC(hScreen, dcScreen);end;procedure TCopyScrThread.SplitBmp2Streams;
var
BmpNo: integer;
BmpX,BmpY: integer; //要拷贝的图像在整个图的行号和列号
PreWidth,PreHeight: integer; //每块要拷贝的图像宽度和高度
x1,x2,y1,y2: integer; //要拷贝的图像的两起始角位置begin
PreWidth := trunc(Screen.Width/8);
PreHeight := trunc(Screen.Height/8);//http://www.delphibbs.com/delphibbs/dispq.asp?lid=440449 SplitedBmp.Width := PreWidth;
SplitedBmp.Height := PreHeight; for BmpY := 0 to 7 do
begin
for BmpX := 0 to 7 do
begin
x1 := PreWidth*BmpX;
y1 := PreHeight*BmpY;
x2 := x1 + PreWidth;
y2 := y1 + PreHeight; BmpNo := BmpY*8 + BmpX;
//如果去掉以下一句, 速度将变得很快
SplitedBmp.Canvas.CopyRect(Rect(0,0,PreWidth,PreHeight), DemoFullBmp.Canvas, Rect(x1,y1,x2,y2));
Application.ProcessMessages; DemoStreams[BmpNo].Clear;
DemoStreams[BmpNo].Position := 0; SplitedBmp.SaveToStream(DemoStreams[BmpNo]); Application.ProcessMessages;
end;
end;end;end.
Windows,SysUtils,Classes,Forms,Graphics;type
TCopyScrThread = class(TThread)
private
DemoFullBmp: TBitmap; // 整屏图像
SplitedBmp: TBitmap; // 块区临时图像 procedure CopyScreen; // 取整屏图像保存在DemoFullBmp
procedure SplitBmp2Streams; // 把整屏图像分为8*8个区块, 保存在DemoStreams
protected
procedure DoTerminate;override;
procedure Execute; override;
public
constructor Create(Suspended:Boolean);
destructor Destroy(); override;
end;implementation
var
DemoStreams:array[0..63] of TMemoryStream; //保存获取的8*8个区图像流constructor TCopyScrThread.Create(Suspended:Boolean);
var
i: integer;
begin
inherited Create(Suspended);
FreeOnTerminate := true; DemoFullBmp := TBitmap.Create; SplitedBmp := TBitmap.Create;
SplitedBmp.PixelFormat := pf15bit; for i:=0 to 63 do
DemoStreams[i] := TMemoryStream.Create;
end;destructor TCopyScrThread.Destroy();
var
i: integer;
begin
inherited Destroy;
DemoFullBmp.Free;
SplitedBmp.Free;
for i:=0 to 63 do
DemoStreams[i].Free;
end;procedure TCopyScrThread.DoTerminate;
begin
inherited DoTerminate;
end;procedure TCopyScrThread.Execute;
begin
while not Terminated and not Suspended do
begin
Synchronize(CopyScreen);
Application.ProcessMessages;
Synchronize(SplitBmp2Streams);
Application.ProcessMessages;
end;
end;procedure TCopyScrThread.CopyScreen;
var
hCursor:integer;
ptCursor:TPoint;
icoCursor:TIcon;
iconInfoCursor:TIconInfo;
intThreadld: dword; hScreen:integer;
dcScreen:integer;
rectScreen:TRect;
begin
hScreen := GetDesktopWindow();
dcScreen := GetDC(hScreen); Application.ProcessMessages; GetWindowRect(hScreen, rectScreen);
DemoFullBmp.Width := rectScreen.Right-rectScreen.Left;
DemoFullBmp.Height := rectScreen.Bottom-rectScreen.Top;
BitBlt(DemoFullBmp.Canvas.Handle, 0, 0, DemoFullBmp.Width, DemoFullBmp.Height, dcScreen, 0, 0, SRCCOPY);
Application.ProcessMessages; ReleaseDC(hScreen, dcScreen);end;procedure TCopyScrThread.SplitBmp2Streams;
var
BmpNo: integer;
BmpX,BmpY: integer; //要拷贝的图像在整个图的行号和列号
PreWidth,PreHeight: integer; //每块要拷贝的图像宽度和高度
x1,x2,y1,y2: integer; //要拷贝的图像的两起始角位置begin
PreWidth := trunc(Screen.Width/8);
PreHeight := trunc(Screen.Height/8);//http://www.delphibbs.com/delphibbs/dispq.asp?lid=440449 SplitedBmp.Width := PreWidth;
SplitedBmp.Height := PreHeight; for BmpY := 0 to 7 do
begin
for BmpX := 0 to 7 do
begin
x1 := PreWidth*BmpX;
y1 := PreHeight*BmpY;
x2 := x1 + PreWidth;
y2 := y1 + PreHeight; BmpNo := BmpY*8 + BmpX;
//如果去掉以下一句, 速度将变得很快
SplitedBmp.Canvas.CopyRect(Rect(0,0,PreWidth,PreHeight), DemoFullBmp.Canvas, Rect(x1,y1,x2,y2));
Application.ProcessMessages; DemoStreams[BmpNo].Clear;
DemoStreams[BmpNo].Position := 0; SplitedBmp.SaveToStream(DemoStreams[BmpNo]); Application.ProcessMessages;
end;
end;end;end.
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货