Here is some code fragment I wrote before, I use incremental image
check and dcom todo
it,
//Sender code
unit u_SnapThread;
interface
uses
Classes,
MonClient_TLB, dbugintf
type
TSnapThread = class (TThread)
protected
FActive : boolean;
FisFirstSnap : boolean;
FRefreshCount: integer;
FInterval : integer;
FWidth : integer;
FHeight : integer;
FSnapEvent : IMonCliEvents;
public
constructor Create (
const AInterval, AWidth, AHeight : integer;
ASnapEvent : IMonCliEvents
);
destructor Destroy;
override;
procedure Execute;
override;
property Active : boolean read FActive;
end;
type
PRGB24 = ^TRGB24;
TRGB24 = packed record
b, g, r: byte;
end;
PRGB24Array = ^TRGB24Array;
TRGB24Array = packed array[0..maxint div sizeof(TRGB24) - 1] of TRGB24;
implementation
uses
Windows, Messages, SysUtils,
Controls, ExtCtrls, Graphics,
Forms , Variants
Const
INT_Refresh=10;
INT_CheckSize=50;
INT_CheckRate=6;
{ TSnapThread }
constructor TSnapThread.Create (
const AInterval, AWidth, AHeight : integer;
ASnapEvent : IMonCliEvents
);
begin
inherited Create (TRUE);
FInterval := AInterval;
FWidth := AWidth;
FHeight := AHeight;
FSnapEvent := ASnapEvent;
// FSnapEvent := TObjectMarshaler.CreateMarshalObject (IMonCliEvents, ASnapEvent);
end;
destructor TSnapThread.Destroy;
begin
inherited;
end;
procedure TSnapThread.Execute;
var
timerCounter:integer;
LastSnapbmp : TBitmap;
Procedure SendBmpChip( pBmpChip:TBitmap;
px,py:integer)
var
TransBuff:OleVariant;
P: Pointer;
lx,ly:OleVariant;
Stream : TMemoryStream;
begin
Stream:=TMemoryStream.Create;
pBmpChip.SaveToStream(Stream);
// SendDebug('Send:'+inttostr(Stream.Size));
TransBuff := varArrayCreate([0, Stream.Size], varByte);
try
P := VarArrayLock(TransBuff);
try
Move(Stream.Memory^, P^, Stream.Size);
finally
VarArrayUnlock(TransBuff);
end;
lx:=OleVariant(px);
ly:=OleVariant(py);
FSnapEvent.EventFired(TransBuff,lx,ly);
finally
TransBuff:=null;
Stream.Free;
end;
end;
procedure CompareBitmap(bmpSource, bmpDest:TBitmap;
CheckSize,CheckRate:integer);
function CompareRGB(RGBFirst,RGBSecond:TRGB24):boolean;
begin
if (RGBFirst.b=RGBSecond.b) and
(RGBFirst.g=RGBSecond.g) and
(RGBFirst.r=RGBSecond.r)
// and (RGBFirst.a=RGBSecond.a)
then
begin
result:=true ;
end
else
begin
result:=false;
end;
end;
function CompareColor(RGBFirst,RGBSecond:TColor):boolean;
begin
if RGBFirst=RGBSecond then
begin
result:=true
end
else
begin
result:=false;
end;
end;
var
x, i, j, k: integer;
sl: PRGB24Array;
s2: PRGB24Array;
Xcount, Ycount:integer;
bmpCheck1, bmpCheck2: TBitmap;
isDiff:boolean;
begin
try
bmpCheck1:=TBitmap.Create;
bmpCheck2:=TBitmap.Create;
bmpCheck1.Width:=CheckSize;
bmpCheck2.Width:=CheckSize;
bmpCheck1.Height:=CheckSize;
bmpCheck2.Height:=CheckSize;
Xcount:= bmpSource.Width div CheckSize;
Ycount:= bmpSource.Height div CheckSize;
for j:= 0 to Ycountdo
begin
for i := 0 to Xcountdo
begin
bmpCheck1.Canvas.CopyRect(Rect(0,0,CheckSize,CheckSize) ,
bmpSource.Canvas,
Rect(i*CheckSize,j*CheckSize,(i+1)*CheckSize,(j+1)*CheckSize))
bmpCheck2.Canvas.CopyRect(Rect(0,0,CheckSize,CheckSize) ,
bmpDest.Canvas,
Rect(i*CheckSize,j*CheckSize,(i+1)*CheckSize,(j+1)*CheckSize))
isDiff:=false;
for k:=1 to CheckSize-1do
begin
if k mod CheckRate<>0 then
Continue;
// sl := bmpCheck1.ScanLine[k];
// s2 := bmpCheck2.ScanLine[k];
for x := 0 to CheckSize - 1do
begin
if x mod CheckRate<>0 then
Continue;
if not CompareColor(bmpCheck1.Canvas.pixels[x,k],
bmpCheck2.Canvas.pixels[x,k]) then
// if not CompareRGB(sl[x],s2[x]) then
begin
SendBmpChip(bmpCheck2, i*CheckSize,j*CheckSize);
isDiff:=true;
break;
end;
end;
if isDiff then
break;
end;
end;
end;
finally
bmpCheck1.Free;
bmpCheck2.Free;
end;
end;
proceduredo
Snap(const Limitwidth, Limitheight:integer);
var
DC:hwnd;
BackgroundCanvas:tcanvas;
backgroundbmp:tbitmap;
begin
DC := GetDC (0);
BackgroundCanvas := TCanvas.Create;
BackgroundCanvas.Handle := DC;
backgroundbmp:=tbitmap.create;
backgroundbmp.width:=Limitwidth
backgroundbmp.height:=Limitheight
backgroundbmp.Canvas.CopyRect (Rect (0, 0, Limitwidth, Limitheight), BackgroundCanvas,
Rect (0, 0, Screen.Width, Screen.Height));
try
if (FisFirstSnap) or (FRefreshCount=INT_Refresh) then
begin
SendBmpChip(backgroundbmp, 0, 0 );
FRefreshCount:=0;
FisFirstSnap:=false;
end
else
CompareBitmap(LastSnapBmp, backgroundbmp, INT_CheckSize, INT_CheckRate);
LastSnapBmp.Assign(backgroundbmp);
finally
backgroundbmp.free;
BackgroundCanvas.free;
end;
end;
begin
{ initialize new thread into an STA }
FActive := TRUE;
FisFirstSnap:=true;
FRefreshCount:=0;
LastSnapbmp:=TBitmap.create;
// InitializeCOM (TRUE, atSTA);
{ unmarshal SearchStatus callback interface so we can use it from this thread }
// FSnapEvent.UnMarshalObject (PSnapEvent);
while not (Terminated)do
begin
inc(FRefreshCount);
do
Snap (FWidth, FHeight);
Sleep(FInterval)
end;
{ uninitialize thread from STA }
// InitializeCOM (FALSE, atSTA);
LastSnapbmp.Free;
FActive := FALSE;
end;
end.
end.
// Receiver code
procedure Tfm_Snap.ConvertData(const Value, px, py: OleVariant);
var
Stream: TMemoryStream;
SnapBmp: TBitmap;
P: Pointer;
begin
if VarIsNull(Value) or VarIsEmpty(Value) then
else
begin
Stream := TMemoryStream.Create;
SnapBmp:= TBitmap.Create;
try
Stream.Size := VarArrayHighBound(Value, 1);
// SendDebug('get:'+inttostr(Stream.Size));
P := VarArrayLock(Value);
try
Stream.Write(P^, Stream.Size);
finally
VarArrayUnlock(Value);
end;
inc(FCount);
Stream.Position := 0;
SnapBmp.LoadFromStream(Stream);
Canvas.StretchDraw(Rect(integer(px), integer(py),
SnapBmp.Width+integer(px), SnapBmp.Height+ integer(py)),
SnapBmp);
if (SnapBmp.Width>Width) or (SnapBmp.Height>Height-80) then
begin
Width:=SnapBmp.Width;
Height:=SnapBmp.Height+40;
end;
finally
SnapBmp.Free;
Stream.Free;
end;
end;
end;