Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / June 2007

Tip: Looking for answers? Try searching our database.

Why CopyFromScreeen and not CopyToScreen?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
bern11 - 29 Jun 2007 04:18 GMT
CopyFromScreen has alot of cool options in the CopyPixelOperation
enumeration.  But, I don't get it.  I want to overlay bitmaps using the
various options, so I have to first draw each on screen then copy it to
a graphics object????  Doesn't sound right, I must be missing something,
what is it?
Peter Duniho - 29 Jun 2007 04:31 GMT
> CopyFromScreen has alot of cool options in the CopyPixelOperation  
> enumeration.  But, I don't get it.  I want to overlay bitmaps using the  
> various options, so I have to first draw each on screen then copy it to  
> a graphics object????  Doesn't sound right, I must be missing something,  
> what is it?

CopyFromScreen exists to get the bits from a specific place: the displayed  
video buffer.  There's no requirement that when you draw, you draw to the  
screen.

If you want to composite a variety of bitmaps without drawing them to the  
screen, simply create a Bitmap instance of appropriate size for your  
operations, use Graphics.FromImage() to get a Graphics instance from that  
Bitmap, and then draw each of your other Bitmap instances using the  
various options you would have used drawing to the screen instead.

After doing that, you will have a final Bitmap instance that is the same  
as if you had drawn everything to the screen and then used CopyFromScreen  
to get the results.

Pete
bern11 - 29 Jun 2007 22:54 GMT
>> CopyFromScreen has alot of cool options in the CopyPixelOperation  
>> enumeration.  But, I don't get it.  I want to overlay bitmaps using
[quoted text clipped - 18 lines]
>
> Pete

But CopyFromScreen doesn't take a bitmap or 2nd graphics as an argument.
 It appears to copy from one part of a graphics object to another.  I
could extend the graphics object to have an off-screen area, draw there,
then copy (with the desired effects options).  That is the way I am
thinking now.  I was hoping to avoid a DrawImage-then-Copy.  Thinking
about it, it looks like a video-memory-type operation where you would
keep objects off-screen but in video memory for fast copies.
Unfortunately, when it was brought into GDI, its functionality wasn't
extended.

Memory is cheap - I'll just size the graphics object for twice the
screen-size.
Peter Duniho - 29 Jun 2007 23:14 GMT
> But CopyFromScreen doesn't take a bitmap or 2nd graphics as an argument.

And that's relevant how?  My point is that it's the wrong method to use,  
given what it _appears_ you asked about doing.  The parameters it takes or  
does not take aren't relevant because you shouldn't be using it.  It is  
specifically for taking an image from the screen, and copying it somewhere  
else (for example, a Graphics instance you got from a different Bitmap  
instance).  If you don't want to start by drawing to the screen in the  
first place, you can't use CopyFromScreen.

>   It appears to copy from one part of a graphics object to another.

The CopyFromScreen method copies a specified area from the screen _to_ the  
Graphics instance on which it's called.  It does not "copy from one part  
of a graphics object to another" unless the Graphics instance used to call  
the method turns out to represent the screen itself.

> I could extend the graphics object to have an off-screen area, draw  
> there, then copy (with the desired effects options).  That is the way I  
> am thinking now.

How, exactly, do you intend to "extend the graphics object"?  If you have  
a Graphics instance that currently represents the screen, it's not like  
you can just tell it "okay, you're now twice as big".

Conversely, if your Graphics instance doesn't represent the screen, then  
you're already dealing with an off-screen image.

It _seems_ to me that you are trying to take advantage of the  
CopyPixelOperation enumeration without actually drawing the source image  
to the screen, but unfortunately there's just no way (that I know of) to  
do that using the Graphics class in .NET.

Now, all that said, the underlying source for this enumeration is the  
drawing modes found in the native Windows HDC object.  So, if what you  
want is off-screen drawing that uses something more complex than the two  
compositing modes that the Graphics class does offer, that's one approach.

It may be that the Windows Presentation Foundation also offers something  
along these lines.  I haven't used it, so I don't know.  Guess I ought to  
upgrade to .NET 3.0 some day.  :)

Pete
bern11 - 30 Jun 2007 03:46 GMT
>> But CopyFromScreen doesn't take a bitmap or 2nd graphics as an argument.
>
[quoted text clipped - 12 lines]
> part  of a graphics object to another" unless the Graphics instance used
> to call  the method turns out to represent the screen itself.

yup.  Any idea if the function could be fooled into thinking another
graphics object is the screen?  I am using a BufferedGraphicsContext, so
I am doing off-screen rendering.

>> I could extend the graphics object to have an off-screen area, draw  
>> there, then copy (with the desired effects options).  That is the way
[quoted text clipped - 3 lines]
> have  a Graphics instance that currently represents the screen, it's not
> like  you can just tell it "okay, you're now twice as big".

//BufferedGraphicsContext.Allocate Method (Graphics, Rectangle)
// Allocates a graphics buffer using the pixel format
// of the specified Graphics object.
grafx = appDomainBufferedGraphicsContext.Allocate(this.CreateGraphics(),
     new Rectangle( 0, 0, screenHeight, screenWidth*2 ));

// Now you're twice as big :)

> Conversely, if your Graphics instance doesn't represent the screen,
> then  you're already dealing with an off-screen image.
[quoted text clipped - 3 lines]
> image  to the screen, but unfortunately there's just no way (that I know
> of) to  do that using the Graphics class in .NET.

YUP (unfortunately)

> Now, all that said, the underlying source for this enumeration is the  
> drawing modes found in the native Windows HDC object.  So, if what you  
> want is off-screen drawing that uses something more complex than the
> two  compositing modes that the Graphics class does offer, that's one
> approach.

Don't want to go there.
I messed around trying to mix HDC object calls with managed drawing, it
got extremely complicated very quickly

> It may be that the Windows Presentation Foundation also offers
> something  along these lines.  I haven't used it, so I don't know.  
> Guess I ought to  upgrade to .NET 3.0 some day.  :)
>
> Pete

so many cool options, just out of reach......
Peter Duniho - 30 Jun 2007 06:24 GMT
> yup.  Any idea if the function could be fooled into thinking another  
> graphics object is the screen?

Doubtful.  Especially if you are already shy about mixing managed and  
unmanaged rendering.  Even if possible, I would guess that somehow  
impersonating the display video buffer would be orders of magnitude more  
difficult than just using unmanaged GDI/GDI+ to do your rendering.

> I am using a BufferedGraphicsContext, so I am doing off-screen rendering.

Any particular reason you're doing the double-buffering explicitly?  I  
have found that simply setting the Control's rendering style to  
double-buffered works fine.

In any case, there should be very little difference between using the  
BufferedGraphicsContext and simply creating an intermediate bitmap, at  
least from an API point of view.  I admit, since I'm happy using the  
built-in double-buffering, I have basically no experience with the  
BufferedGraphicsContext, but I suspect that if it has any advantage over  
simply drawing to an intermediate Bitmap instance, it's that it somehow  
uses video memory for the frame buffer, rather than system memory.

> //BufferedGraphicsContext.Allocate Method (Graphics, Rectangle)
> // Allocates a graphics buffer using the pixel format
[quoted text clipped - 3 lines]
>
> // Now you're twice as big :)

Okay...so you have a Graphics instance that does not actually represent  
the screen, which you are drawing to.

Is your reasoning behind expanding the BufferedGraphicsContext that you  
can use CopyFromScreen without incurring the video-memory-to-system-memory  
performance hit?  If so: have you confirmed that there is a significant  
performance hit for your usage? and have you confirmed that using  
BufferedGraphicsContext avoids that?

In particular, if BufferedGraphicsContext doesn't actually allow you to do  
a video-memory-to-video-memory copy, then it's not really getting you  
anything except more complication.  Even if it does do that, keep in mind  
that with PCI-E, there is no longer the terrible asymmetric data bandwidth  
going from the video to system memory versus the other direction.

Basically, it seems like you've created a fairly complicated scenario, one  
that is no less complicated than would be simply using unmanaged GDI to  
composite your bitmaps.

Even if the expansion of the BufferedGraphicsContext does what it seems  
like you're hoping it does, you still have to draw all of your data to the  
screen sequentially, copying it back to the BufferedGraphicsContext to get  
the compositing you want, and then presumably copy the result back to the  
screen.  You might get that to happen quickly, but I doubt you can get it  
to happen quickly enough that the user won't notice (in particular, I'd  
expect a fair amount of flickering as the different images get put on the  
screen so that you can copy them back to your off-screen Graphics  
instance).

> [...]
>> Now, all that said, the underlying source for this enumeration is the  
[quoted text clipped - 6 lines]
> I messed around trying to mix HDC object calls with managed drawing, it  
> got extremely complicated very quickly

I don't know what you mean by "extremely complicated", but it sure seems  
to me that what you're talking about doing instead is at least as  
complicated.

Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.