Very nice concept.  Thanks for sharing it :-)

[EMAIL PROTECTED] wrote:
> ScreenGrabber is a part of Breeze (also licenced as freeware GNU GPL). 
> You can find full source code on my web pages. Now I'm implementing 2 
> way feed-back-buffer to accelerate and minimize data traffic.
>
> 1. call method Grab to find minimal changed rectangle (on the screen).
> 2. call GrabAccept.
> 3. in ResultBMP is stored changed bitmapdata.
>
> ScreenGrabber is developed in C++ and Object Pascal. Pascal for graphics 
> issues, C++ for robust logic.
>
> Source code:
>
> unit ScreenChangeRecognition;
>
> interface
>
> uses
>   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
>   StdCtrls, ExtCtrls,Math;
>
> type
>   TPixels = array[0..$FFFFFF] of dword;
>   PPixels = ^TPixels;
>
> type
>   TChangeResult = record
>                     result:boolean; //byly detekovany zmeny
>                     ChangeRect:TRect; //obdelnik ktery se vymenil
>                     KeyFrame:boolean;  //zjisti jestli byl zmenen celyscreen
>                   end;
>
> type
>   TGrabMode = (GM_NORMAL,GM_KEYFRAME,GM_NOTRAYWND);
>
> type
>   TChangeRecognition = class
>   private
>     ScreenDC:HDC;
>     bmp:array [0..1] of TBitmap;
>     pixels:array [0..1] of PPixels; //pole pixelu pro kazdou bitmapu
>     lowbmp:TBitmap; //slouzi pro ulozeni rozdilu
>     lowpix:PPixels; //pixely bitmapy pro detekci zmen
>     counter:dword;  //pocita kolikrat bylo zavolano grab
>     fVideoHeight: integer;
>     fVideoWidth: integer;
>     fVideoX: integer;
>     fVideoY: integer;
>     fVideoH: integer;
>     fVideoW: integer;
>     RectSize:integer;
>     fGrabMode: TGrabMode;
>     procedure setVideoHeight(const Value: integer);
>     procedure setVideoWidth(const Value: integer);
>     procedure setVideoX(const Value: integer);
>     procedure setVideoY(const Value: integer);
>     procedure setVideoH(const Value: integer);
>     procedure setVideoW(const Value: integer);
>   public
>     LastResult:TChangeResult;
>     ResultBMP:TBitmap;  //bitmapa se zmenenou casti
>     procedure Grab; //najde zmeny v obrazu
>     procedure GrabAccept; //akceptuje zmeny
>     function getBitmap:TBitmap;
>     function getLowBMP:TBitmap;
>     constructor create;
>     destructor destroy;
>     procedure setVideoRect(ax,ay,aw,ah,destw,desth:integer);
>     property VideoX:integer read fVideoX write setVideoX;
>     property VideoY:integer read fVideoY write setVideoY;
>     property VideoW:integer read fVideoW write setVideoW;
>     property VideoH:integer read fVideoH write setVideoH;
>     property VideoWidth:integer read fVideoWidth write setVideoWidth;
>     property VideoHeight:integer read fVideoHeight write setVideoHeight;
>     property GrabMode:TGrabMode read fGrabMode write fGrabMode;
>   end;
>
>
> implementation
>
> { TChangeRecognition }
>
> constructor TChangeRecognition.create;
> var a:integer;
> begin
>   //zjisti device context obrazovky
>   ScreenDC:=getDC(0);
>   RectSize:=5;
>
>   //nastavi sirku a vysku videa
>   fVideoWidth:=screen.width;
>   fVideoHeight:=screen.Height;
>   fVideoW:=screen.width;
>   fVideoH:=screen.height;
>
>   fGrabMode:=GM_NORMAL;
>
>   //vytvori bitmapy do nichz bude uklada screen
>   for a:=0 to high(bmp) do
>   begin
>     bmp[a]:=TBitmap.create;
>     bmp[a].Width:=VideoWidth;
>     bmp[a].Height:=VideoHeight;
>     bmp[a].PixelFormat:=pf32bit;
>     //nacte ukazatel
>     pixels[a]:=bmp[a].ScanLine[bmp[a].height-1];
>   end;
>
>   ResultBMP:=TBitmap.create;
>   ResultBMP.PixelFormat:=pf32bit;
>
>   //nastavi rozmery lowbitmapy pro detekci rozdilu
>   lowbmp:=TBitmap.create;
>   //bitmapa musi byt vetsi o 3 pixely nebot se predsazuje pixel
>   //dopredu a 2 pixely dozadu
>   lowbmp.Width:=trunc(bmp[0].Width/RectSize)+3;
>   lowbmp.Height:=trunc(bmp[0].Height/RectSize)+3;
>   lowbmp.PixelFormat:=pf32bit;
>   //nacte pixely
>   lowpix:=lowbmp.ScanLine[lowbmp.height-1];
> end;
>
>
>
>
> destructor TChangeRecognition.destroy;
> begin
>
> end;
>
>
>
> //nastavi vysky videa
> function TChangeRecognition.getBitmap: TBitmap;
> var whichBMP:integer;
> begin
>   whichBMP:=(counter mod (high(bmp)+1));
>   result:=bmp[whichBMP];
>   result:=bmp[0];
> end;
>
>
>
>
> function TChangeRecognition.getLowBMP: TBitmap;
> begin
>   result:=lowbmp
> end;
>
>
>
>
> procedure TChangeRecognition.grab;
> var whichBMP:integer; //ktera bitmapa se pouzije
>     x,y:integer;
>     startx,starty:integer; //startovaci pozice aby bylo mozne detekovat 
> zmeny
>     position:integer; //pozice v poli pixelu ktera se porovnava
>     pix1,pix2:PPixels; //pole pixelu pro porovnani a detekci zmen
>     xscale,yscale:single; //koeficienty roztazeni okna
>     TrayWnd:hwnd; //okno jehoz zmeny se nezaznamenavaji
>     TrayWndRect:TRect;
> begin
>   counter:=counter+1;
>   //zjisti do ktere bitmapy se bude tisknout tentokrat
>   whichBMP:=(counter mod (high(bmp)+1));
>   whichBMP:=1;
>   //pokud jsou strany obdelniku a,b source a dest stejne tak provede bitblt
>   if ((VideoW=VideoWidth) and (VideoH=VideoHeight)) then
>   begin
>     bitblt(bmp[whichBMP].Canvas.Handle,
>            0,0,bmp[whichBMP].Width,bmp[whichBMP].Height,
>            ScreenDC,VideoX,VideoY,srccopy);
>   end
>   //jinak provede stretchblt
>   else
>   begin
>     SetStretchBltMode(bmp[whichBMP].Canvas.Handle,HALFTONE);
>     //zmensi bitmapu
>     StretchBlt(bmp[whichBMP].Canvas.Handle,
>            0,0,bmp[whichBMP].Width,bmp[whichBMP].Height,
>            ScreenDC,VideoX,VideoY,VideoW,VideoH,srccopy);
>   end;
>
>   //pokud je snimek klicovym obrazkem tak neni treba vypocitavat 
> nejmensi obdelnik
>   if GrabMode=GM_KEYFRAME then
>   begin
>     LastResult.result:=true;
>     LastResult.ChangeRect:=rect(0,0,VideoWidth,VideoHeight);
>     LastResult.KeyFrame:=true;
>     exit;
>   end;
>
>   //zjisti handle traywnd
>   TrayWnd:=FindWindow('Shell_TrayWnd',nil);
>   if not(getwindowrect(TrayWnd,TrayWndRect)) then
>     TrayWndRect:=rect(0,0,0,0);
>    
>   //zjisti koeficient roztazeni z puvodni oblasti do nove
>   xscale:=(VideoW)/VideoWidth;
>   yscale:=(VideoH)/VideoHeight;
>
>   //resetuje posledni vysledek
>   LastResult.result:=false;
>   LastResult.ChangeRect:=rect($FFFF,$FFFF,-1,-1);
>   LastResult.KeyFrame:=false;
>
>   //premaze lowbmp
>   zeromemory(@lowpix[0],lowbmp.width*lowbmp.height*sizeof(dword));
>
>   //v pix1 je ulozena aktualni mapa v pix2 stara podle niz se porovnava
>   pix1:=pixels[whichBMP];
>   pix2:=pixels[abs(whichBMP-1)];
>
>   //urci startovni pozice x a y
>   startx:=counter mod RectSize;
>   starty:=trunc(counter/RectSize) mod RectSize;
>  
>   //prohleda zmeny v obrazku
>   //nastavi y na pocatek
>   y:=starty;
>   while y<VideoHeight do
>   begin
>     //nastavi x na pocatek
>     x:=startx;
>     while x<VideoWidth do
>     begin
>       //zjisti jestli se na dotycnem miste nenachazi traywnd
>       if GrabMode=GM_NOTRAYWND then
>         if ptinrect(TrayWndRect,point(trunc(x*xscale),
>                                 trunc((VideoHeight-y)*yscale))) then
>         begin
>           x:=x+RectSize;
>           continue;
>         end;
>       //v ramci na hodnote counter systematicky prochazi obrazovku
>       //pokud je steprect 8 a obraz se scanuje 4 krat za vterinu
>       //je stredni doba nalezeni zmeny pixelu 8 vterin
>       position:=y*VideoWidth+x;
>       if(pix1[position]<>pix2[position]) then
>       with LastResult do
>       begin
>         result:=true;
>         //upravi minimalni obdelnik ve kterem doslo ke zmenam
>         ChangeRect:=rect(min(ChangeRect.Left,x-RectSize),
>                          min(ChangeRect.Top,y-RectSize),
>                          max(ChangeRect.Right,x+RectSize),
>                          max(ChangeRect.Bottom,y+RectSize));
>         //zmeni pixel v lowbmp
>         //pozor x je ve skutecnosti x-1 nebot lowbmp je predsazena
>         //lowpix[y*lowbmp.Width+x]:=$000000FF;
>         //lowpix[y*lowbmp.Width+x+1]:=$000000FF;
>         //lowpix[y*lowbmp.Width+x+2]:=$000000FF;
>         //lowpix[(y+1)*lowbmp.Width+x+2]:=$000000FF;
>         //lowpix[(y+2)*lowbmp.Width+x+2]:=$000000FF;
>       end;
>       //inkrementuje x
>       x:=x+RectSize;
>     end;
>     //inkrementuje y
>     y:=y+RectSize;
>   end;
>
>
>
>   //vysledny obdelnik je jeste treba upravit
>   if LastResult.result then
>   with LastResult do
>   begin
>     {//zameni souradnice tak aby byl pocatek vlevo nahore
>     
> ChangeRect:=rect(VideoX+ChangeRect.Left,VideoY+VideoHeight-ChangeRect.Bottom,
>                      
> VideoX+ChangeRect.Right,VideoY+VideoHeight-ChangeRect.Top);
>     //upravi obdelnik aby se vesel do vyrezu obrazku
>     ChangeRect:=rect(max(ChangeRect.Left,VideoX),
>                      max(ChangeRect.Top,VideoY),
>                      min(ChangeRect.Right,VideoX+VideoWidth),
>                      min(ChangeRect.Bottom,VideoY+VideoHeight));}
>
>     //zameni souradnice tak aby byl pocatek vlevo nahore
>     ChangeRect:=rect(ChangeRect.Left,VideoHeight-ChangeRect.Bottom,
>                      ChangeRect.Right,VideoHeight-ChangeRect.Top);
>     //upravi obdelnik aby se vesel do vyrezu obrazku
>     ChangeRect:=rect(max(ChangeRect.Left,0),
>                      max(ChangeRect.Top,0),
>                      min(ChangeRect.Right,VideoWidth),
>                      min(ChangeRect.Bottom,VideoHeight));
>   end;
> end;
>
>
>
>
> procedure TChangeRecognition.GrabAccept;
> begin
>   //pokud je vysledek grab kladny je volana metoda grabaccept
>   //ktera detekuje bitmapu jez se zmenila
>   if LastResult.result then
>   begin
>     //zjisti velikost ResultBMP
>     ResultBMP.width:=LastResult.ChangeRect.Right-LastResult.ChangeRect.Left;
>     
> ResultBMP.Height:=LastResult.ChangeRect.Bottom-LastResult.ChangeRect.Top;
>     //zjisti bitmapu vysledku
>     bitblt(ResultBMP.Canvas.Handle,0,0,ResultBMP.Width,ResultBMP.Height,
>            bmp[1].canvas.handle,
>            LastResult.ChangeRect.Left,LastResult.ChangeRect.Top,srccopy);
>     //ulozi zmenenou cast do bmp1
>     bitblt(bmp[0].Canvas.Handle,
>            LastResult.ChangeRect.Left,LastResult.ChangeRect.Top,
>            ResultBMP.width,ResultBMP.height,
>            ResultBMP.canvas.handle,0,0,srccopy);
>   end;
> end;
>
>
>
>
>
> procedure TChangeRecognition.setVideoH(const Value: integer);
> begin
>   fVideoH := min(screen.Height,Value);
> end;
>
>
>
>
> procedure TChangeRecognition.setVideoHeight(const Value: integer);
> var a:integer;
> begin
>   //nastavi vysku videa
>   fVideoHeight := min(screen.Height,max(Value,1));
>   //zmeni rozliseni videa
>   for a:=0 to high(bmp) do
>   begin
>     bmp[a].Height:=VideoHeight;
>     pixels[a]:=bmp[a].ScanLine[bmp[a].height-1];
>     //musi upravit i lowbmp
>     lowbmp.Height:=trunc(bmp[0].Height/RectSize)+3;
>     lowpix:=lowbmp.ScanLine[lowbmp.height-1];
>   end;
> end;
>
>
>
>
> procedure TChangeRecognition.setVideoRect(ax, ay, aw, ah, destw, desth: 
> integer);
> begin
>   VideoX:=ax;
>   VideoY:=ay;
>   VideoW:=aw;
>   VideoH:=ah;
>   VideoWidth:=destw;
>   VideoHeight:=desth;
> end;
>
>
>
> procedure TChangeRecognition.setVideoW(const Value: integer);
> begin
>   fVideoW := min(screen.Width,Value);
> end;
>
>
>
>
> procedure TChangeRecognition.setVideoWidth(const Value: integer);
> var a:integer;
> begin
>   //nastavi sirku videa
>   fVideoWidth := min(screen.Width,max(Value,1));
>   //zmeni rozliseni videa
>   for a:=0 to high(bmp) do
>   begin
>     bmp[a].Width:=VideoWidth;
>     pixels[a]:=bmp[a].ScanLine[bmp[a].height-1];
>     //musi upravit i lowbmp
>     lowbmp.Width:=trunc(bmp[0].Width/RectSize)+3;
>     lowpix:=lowbmp.ScanLine[lowbmp.height-1];
>   end;
> end;
>
>
>
>
> procedure TChangeRecognition.setVideoX(const Value: integer);
> begin
>   fVideoX := max(Value,0);
> end;
>
>
>
>
> procedure TChangeRecognition.setVideoY(const Value: integer);
> begin
>   fVideoY := max(Value,0);
> end;
>
> end.
>
> Interalab napsal(a):
>   
>> Is the screengrabber application proprietary?
>>
>> [EMAIL PROTECTED] wrote:
>>   
>>     
>>> Hi.
>>>
>>> Im so sorry i forgot change "licence" paragraph text. But as you can see 
>>> on my web pages http://www.cze.cz/?lang=en, the licence is GNU GPL.
>>>
>>> dabi du napsal(a):
>>>   
>>>     
>>>       
>>>> Hi, very interesting work.
>>>>
>>>> Could you please explain about terms of use, you say
>>>> freeware open source but on your web site it says only
>>>> for noncommercial us. How is it going to be in the
>>>> future in terms of licesing.
>>>>
>>>> --- John Grden <[EMAIL PROTECTED]> wrote:
>>>>
>>>>   
>>>>     
>>>>       
>>>>         
>>>>> wow, very impressive video - The screen capture, i"m
>>>>> sure, is going to get
>>>>> alot of people trying it out for sure.  That was
>>>>> very cool to see.
>>>>>
>>>>> Nice work!
>>>>>
>>>>> On 4/15/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
>>>>>     
>>>>>       
>>>>>         
>>>>>           
>>>>>> **Breeze is freeware open source web application
>>>>>>       
>>>>>>         
>>>>>>           
>>>>>>             
>>>>> for chating, providing
>>>>>     
>>>>>       
>>>>>         
>>>>>           
>>>>>> and recording web seminars.
>>>>>>
>>>>>> Download (Windows & Linux all in one)
>>>>>> Download from
>>>>>>       
>>>>>>         
>>>>>>           
>>>>>>             
>>>>> http://rapidshare.com/files/25850249/Breeze.exe
>>>>> (28118 KB)
>>>>>     
>>>>>       
>>>>>         
>>>>>           
>>>>>> or http://mirror1.cze.cz/download/breeze.exe
>>>>>>       
>>>>>>         
>>>>>>           
>>>>>>             
>>>>> (28118 KB).
>>>>>     
>>>>>       
>>>>>         
>>>>>           
>>>>>> Online video tutorial
>>>>>>       
>>>>>>         
>>>>>>           
>>>>>>             
>>>>> http://grafitchat.wz.cz/help.htm,
>>>>>     
>>>>>       
>>>>>         
>>>>>           
>>>>>> http://mirror1.cze.cz/download/breezehelp.htm.
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> Red5 mailing list
>>>>>> [email protected]
>>>>>>
>>>>>>       
>>>>>>         
>>>>>>           
>>>>>>             
>>>>> http://osflash.org/mailman/listinfo/red5_osflash.org
>>>>>     
>>>>>
>>>>> -- 
>>>>> [  JPG  ]
>>>>>     
>>>>>       
>>>>>         
>>>>>           
>>>>>> _______________________________________________
>>>>>>       
>>>>>>         
>>>>>>           
>>>>>>             
>>>>> Red5 mailing list
>>>>> [email protected]
>>>>> http://osflash.org/mailman/listinfo/red5_osflash.org
>>>>>
>>>>>     
>>>>>       
>>>>>         
>>>>>           
>>>> __________________________________________________
>>>> Do You Yahoo!?
>>>> Tired of spam?  Yahoo! Mail has the best spam protection around 
>>>> http://mail.yahoo.com 
>>>>
>>>> _______________________________________________
>>>> Red5 mailing list
>>>> [email protected]
>>>> http://osflash.org/mailman/listinfo/red5_osflash.org
>>>>
>>>>
>>>>
>>>>   
>>>>     
>>>>       
>>>>         
>>> _______________________________________________
>>> Red5 mailing list
>>> [email protected]
>>> http://osflash.org/mailman/listinfo/red5_osflash.org
>>>   
>>>     
>>>       
>> _______________________________________________
>> Red5 mailing list
>> [email protected]
>> http://osflash.org/mailman/listinfo/red5_osflash.org
>>
>>
>>
>> __________ Informace od NOD32 2195 (20070416) __________
>>
>> Tato zprava byla proverena antivirovym systemem NOD32.
>> http://www.nod32.cz
>>
>>
>>
>>   
>>     
>
>
> _______________________________________________
> Red5 mailing list
> [email protected]
> http://osflash.org/mailman/listinfo/red5_osflash.org
>   

_______________________________________________
Red5 mailing list
[email protected]
http://osflash.org/mailman/listinfo/red5_osflash.org

Reply via email to