BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

pb with TBitmap

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Graphics
View previous topic :: View next topic  
Author Message
Romain Chagot
Guest





PostPosted: Sun Jul 27, 2003 8:11 pm    Post subject: pb with TBitmap Reply with quote



I get a HBitmap and i assign it to a TBitmap.handle property...
after i want to assign the tbitmap to a TJpegImage component but it doesn't
work... i get a white picture :/

image: TPaintBox;
hdcCompatible: HBITMAP;


procedure TForm1.FormCreate(Sender: TObject);
begin
bmp := TBitmap.Create;
jpg := TJpegImage.Create;
stream := TMemoryStream.Create;

hdcScreen := CreateDC('DISPLAY', nil, nil, nil);

screen_width := GetDeviceCaps(hdcScreen, HORZRES);
screen_height := GetDeviceCaps(hdcScreen, VERTRES);

bmp.width := 640; //static values only for test and to speed up
computing
bmp.height := 480;
//bmp.width := screen_width;
//bmp.height := screen_height;

//------- initializations for screenshoting -------------
hdcCompatible := CreateCompatibleDC(hdcScreen);

hbmScreen := CreateCompatibleBitmap(hdcScreen, screen_width,
screen_height);

if hbmScreen = 0 then
messagedlg('hbmScreen', mtError, [mbOK], 0);

hSelectObject := SelectObject(hdcCompatible, hbmScreen);

if (hSelectObject = NULLREGION) or (hSelectObject = GDI_ERROR) then
messagedlg('Compatible Bitmap Selection', mtError, [mbOK], 0);
//------- end of initializations -------------


bmp.Canvas.Handle := hdcCompatible; //"bmp.handle := hdcCompatible;"
seems not to work at all

end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
BitBlt(hdcCompatible,
0, 0, bmp.width, bmp.height,
hdcScreen,
0, 0,
SRCCOPY); //taking a screenshot

//image.canvas.Draw(0,0,bmp); //that works

jpg.pixelformat := jf24bit;
jpg.assign(bmp);
jpg.Compress;
image.Canvas.Draw(0,0,jpg); //i get a white picture
jpg.SaveToStream(stream);
client.SendBuffer(stream, stream.size);
stream.clear;
end;



I tried to assign it to another TBitmap instead of a TJpegImage but i failed
too...
the only working way I found is :
bmp2.canvas.draw(0, 0, bmp);
but it's not clean and it slow down computing... I would like to do a 25 fps
treatment (maybe i'm dreaming)



if someone could help me.......

thanx





Back to top
Maynard Philbrook
Guest





PostPosted: Sun Jul 27, 2003 11:02 pm    Post subject: Re: pb with TBitmap Reply with quote



Try to initiate a Canvas in the Timer event to copy the screen data to the
bitmap.
or simply create a global Canvas to save time like this.
// global section
var
screenShotDC:Tcanvas; // create at run time.
ScreenBitmap:TBitmap;// create at run time..
ScreenJpeg:TJpegImage;
---
your timer event
---
Begin
ScreenShotDC.Handle := GetDC(GetDeskTopWindow);
ScreenBitMap.Canvas.CopyRect(ScreenShotDC.ClipRect,ScreenShotDC,
ScreenShotDC.ClipRect);
ReleaseDC(GetDeskTopWindow, ScreenShotDC.Handle);
ScreenJpeg.Assign(ScreenBitMap);
ScreenJpeg.SaveToStream(.....);/



Romain Chagot wrote:

Quote:
I get a HBitmap and i assign it to a TBitmap.handle property...
after i want to assign the tbitmap to a TJpegImage component but it doesn't
work... i get a white picture :/

image: TPaintBox;
hdcCompatible: HBITMAP;

procedure TForm1.FormCreate(Sender: TObject);
begin
bmp := TBitmap.Create;
jpg := TJpegImage.Create;
stream := TMemoryStream.Create;

hdcScreen := CreateDC('DISPLAY', nil, nil, nil);

screen_width := GetDeviceCaps(hdcScreen, HORZRES);
screen_height := GetDeviceCaps(hdcScreen, VERTRES);

bmp.width := 640; //static values only for test and to speed up
computing
bmp.height := 480;
//bmp.width := screen_width;
//bmp.height := screen_height;

//------- initializations for screenshoting -------------
hdcCompatible := CreateCompatibleDC(hdcScreen);

hbmScreen := CreateCompatibleBitmap(hdcScreen, screen_width,
screen_height);

if hbmScreen = 0 then
messagedlg('hbmScreen', mtError, [mbOK], 0);

hSelectObject := SelectObject(hdcCompatible, hbmScreen);

if (hSelectObject = NULLREGION) or (hSelectObject = GDI_ERROR) then
messagedlg('Compatible Bitmap Selection', mtError, [mbOK], 0);
//------- end of initializations -------------

bmp.Canvas.Handle := hdcCompatible; //"bmp.handle := hdcCompatible;"
seems not to work at all

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
BitBlt(hdcCompatible,
0, 0, bmp.width, bmp.height,
hdcScreen,
0, 0,
SRCCOPY); //taking a screenshot

//image.canvas.Draw(0,0,bmp); //that works

jpg.pixelformat := jf24bit;
jpg.assign(bmp);
jpg.Compress;
image.Canvas.Draw(0,0,jpg); //i get a white picture
jpg.SaveToStream(stream);
client.SendBuffer(stream, stream.size);
stream.clear;
end;

I tried to assign it to another TBitmap instead of a TJpegImage but i failed
too...
the only working way I found is :
bmp2.canvas.draw(0, 0, bmp);
but it's not clean and it slow down computing... I would like to do a 25 fps
treatment (maybe i'm dreaming)

if someone could help me.......

thanx

--
To See what real programmers do in their spare time visit
http://jamie12.home.mindspring.com
home of PC bit software ..
Please send comments about my work .



Back to top
Joris
Guest





PostPosted: Mon Jul 28, 2003 4:52 pm    Post subject: Re: pb with TBitmap Reply with quote



"Romain Chagot" <romain.chagot (AT) free (DOT) fr> wrote

Quote:
bmp.Canvas.Handle := hdcCompatible; //"bmp.handle := hdcCompatible;"
seems not to work at all
....
procedure TForm1.Timer1Timer(Sender: TObject);
begin
BitBlt(hdcCompatible,
0, 0, bmp.width, bmp.height,
hdcScreen,
0, 0,
SRCCOPY); //taking a screenshot

You may pull this off if you assign the HBITMAP to bmp.Handle, and next assign the HDC
to bmp.Canvas.Handle. Another option may be to create the TBitmap as you ordinarilly
would, making sure it's a DIB internally, not a DDB, and using the Canvas.Handle to
blit to. But that's probably not the only thing that's wrong with this code...

There's excellent screenshot code around from Joe Hecht. It's been posted here umpty
times, it should be not problem to find it. It may be worthwhile to work from that
starting point instead. Next, try to migrate bitmap building and such from the Timer
event to a single initialization section, like you did, but do it one step at a time
and make sure that things still work, each step.

Quote:
jpg.SaveToStream(stream);
I would like to do a 25 fps
treatment (maybe i'm dreaming)

JPEG is a file format especially suited for continuous tone pictures (photographs and
such), and especially not suited for screenshots. You'll get a very bad compression
ratio, and still a bad quality jpeg. Furthermore, it's not at all suitable if you need
this kind of speed.

Mere bitmap RLE compression is already very good if you're dealing with screenshots.
It's also very extremely fast to compute. I don't know if TBitmap supports saving with
RLE compression, I'm not in the habit of using TBitmap. Another option is PNG, being
carefull to choose the worst possible compression in favor of the best possible speed.

It may also be a good idea to calculate a dirty rectangle, and compress and send only
that dirty rectangle (and some additional info on where to position it, so that the
receiver side can recompose the complete image). That's not too hard, just keep the
previous screenshot around and compare scanline-wise to find to topmost, leftmost,
rightmost, and bottommost pixel that truely differs from that previous screenshot.

While you're comparing to the previous screenshot anyway, it may also be a good idea
to calculate the delta image of the dirty rectangle. Meaning, substract the previous
bytes from the current bytes before doing anything else with 'em. That should result
in dirty rectangles filled with mostly zero's, compressing faster and better in all of
the various compression scemes mentioned earlier. The result could be saved as RLE
bitmaps or high speed compressed PNG's, but it may be even faster to directly feed
this result to a deflate compressor. That way you have complete control over the
deflate compression trade-offs.

25 fps may just be feasible, on fast machines, I think, but you'll have to build and
optimize various strategies, only to be able to compare them and select the faster
one. You're in for a lot of work.


Joris




Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Graphics All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.