[Mono-list] screen capturing in mono

Scott Willeke scott at willeke.com
Wed Feb 28 16:39:02 EST 2007


In theory you could use reflection to call the protected Control.OnPaint 
method to trick it into painting on your bitmap's graphics, but it is 
obviously a hack, and may have security implications (will almost 
certainly require full trust, especially on MS.NET).

Sebastien Pouliot wrote:
> On Wed, 2007-02-28 at 15:34 -0500, Abe Gillespie wrote:
>   
>> Have you tried the DrawToBitmap method?
>>     
>
> Nice one, but 2.0 and not yet implemented in Mono.
>
>   
>> -Abe
>>
>> On 2/28/07, Eric Morgan <eric at rengeo.com> wrote:
>>     
>>> The problem isn't resizing - I don't have an original bitmap to resize.  The
>>> problem is that I have a control that I want a screenshot of.  So, I'm
>>> trying to create a Bitmap from whatever is appearing in the control.
>>>
>>> I pass the control in, then I call control.CreateGraphics();
>>> System.Drawing.Graphics g1 = c.CreateGraphics();
>>>
>>> Then, with the resulting graphics object, I try to create a new bitmap.
>>> Bitmap MyImage = new Bitmap(w, h, g1);
>>>
>>> The thing is, this bitmap is blank, unless I paste back in that BitBlt code.
>>>  I can't figure out how to get a new bitmap from a graphics object, without
>>> BitBlt().
>>>
>>> Sebastien - Using 2.0 isn't an option, unfortunately.
>>>
>>> Is there any alternative from P/Invoking in this case?
>>>
>>> Thanks for all the help!
>>>
>>> Eric
>>>
>>>
>>> On 2/28/07, Abe Gillespie < abe.gillespie at gmail.com> wrote:
>>>       
>>>> It looks like you're just taking the image and resizing it to show in
>>>> the dialog.  You really should not have to go into native OS libraries
>>>> to do so.  Does this site help?
>>>>
>>>> http://www.peterprovost.org/archive/2003/05/29/516.aspx
>>>>
>>>> -Abe
>>>>
>>>> On 2/28/07, Eric Morgan <eric at rengeo.com> wrote:
>>>>         
>>>>> I'm not too sure how to get a Bitmap object from a graphics object.
>>>>>           
>>> From
>>>       
>>>>> all I've read, I just hear that you have to deal with device contexts.
>>>>>           
>>> I'm
>>>       
>>>>> not too familiar with it, but BitBlt seems to be the way to do that.
>>>>>           
>>> What
>>>       
>>>>> would I need to do to get that bitmap created with what appears in the
>>>>> control using 100% .NET so it can run in mono?  Here's a snippet of
>>>>>           
>>> code.
>>>       
>>>>>
>>>>>           
>>> [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
>>>       
>>>>>         private static extern bool BitBlt(
>>>>>             IntPtr hdcDest, // handle to destination DC
>>>>>             int nXDest,  // x-coord of destination upper-left corner
>>>>>             int nYDest,  // y-coord of destination upper-left corner
>>>>>             int nWidth,  // width of destination rectangle
>>>>>             int nHeight, // height of destination rectangle
>>>>>             IntPtr hdcSrc,  // handle to source DC
>>>>>             int nXSrc,   // x-coordinate of source upper-left corner
>>>>>             int nYSrc,   // y-coordinate of source upper-left corner
>>>>>             System.Int32 dwRop  // raster operation code
>>>>>             );
>>>>>
>>>>>
>>>>>         public static Bitmap PerformCapture(Control c, int maxWidth, int
>>>>> maxHeight)
>>>>>         {
>>>>>             try
>>>>>             {
>>>>>                 int w = c.ClientRectangle.Width;
>>>>>                 int h = c.ClientRectangle.Height;
>>>>>
>>>>>                 w = System.Math.Min(w, maxWidth);
>>>>>                 h = System.Math.Min(w, maxHeight);
>>>>>
>>>>>                 System.Drawing.Graphics g1 =
>>>>> c.CreateGraphics();//this.CreateGraphics();
>>>>>                 Bitmap MyImage = new Bitmap(w, h, g1);
>>>>>                 System.Drawing.Graphics g2 =
>>>>> System.Drawing.Graphics.FromImage (MyImage);
>>>>>                 IntPtr dc1 = g1.GetHdc();
>>>>>                 IntPtr dc2 = g2.GetHdc();
>>>>>                 BitBlt(dc2, 0, 0, w, h, dc1, 0, 0, 13369376);
>>>>>                 g1.ReleaseHdc(dc1);
>>>>>                 g2.ReleaseHdc(dc2);
>>>>>
>>>>> //Separate dialog to display the image.  If I comment out the BitBlt
>>>>>           
>>> code,
>>>       
>>>>> it just appears blank.
>>>>>
>>>>>           
>>> Library.Windows.Dialogs.ScreenCaptureDlg
>>>       
>>>>> dlg = new
>>>>> Library.Windows.Dialogs.ScreenCaptureDlg(MyImage);
>>>>>                 dlg.ShowDialog();
>>>>>
>>>>>                 return MyImage;
>>>>>             }
>>>>>             catch(Exception error)
>>>>>             {
>>>>> //our exception handling library.
>>>>>                 Library.Common.ErrMsg.Err( error );
>>>>>                 throw error;
>>>>>
>>>>>             }
>>>>>         }
>>>>>
>>>>>
>>>>>
>>>>> On 2/28/07, Abe Gillespie <abe.gillespie at gmail.com> wrote:
>>>>>           
>>>>>> Are you P/Invoking for performance?  Why not just use the GDI .Net
>>>>>>             
>>> API?
>>>       
>>>>>> -Abe
>>>>>>
>>>>>> On 2/28/07, Eric Morgan <eric at rengeo.com> wrote:
>>>>>>             
>>>>>>> Hi all,
>>>>>>>
>>>>>>> Is there a good way to capture screens or something similar in mono?
>>>>>>>               
>>>  In
>>>       
>>>>> our
>>>>>           
>>>>>>> .NET application, we have custom controls, and we basically create a
>>>>>>> graphics object from it, make a new bitmap, then do a bitblt to get
>>>>>>>               
>>> it
>>>       
>>>>> into
>>>>>           
>>>>>>> the bitmap.  This requires a P/Invoke into gdi32.dll , which
>>>>>>>               
>>> obviously
>>>       
>>>>> blows
>>>>>           
>>>>>>> up in mono.  Is there a good way to do this using mono?  Some other
>>>>>>>               
>>>>> library
>>>>>           
>>>>>>> maybe?
>>>>>>>
>>>>>>> I've tried installing wine and using the gdi32.dll.so that comes
>>>>>>>               
>>> with
>>>       
>>>>> it,
>>>>>           
>>>>>>> but I don't know if I'm using it correctly or not.  It can find the
>>>>>>>               
>>>>> library,
>>>>>           
>>>>>>> but it gives a SIGSEGV while trying to execute the bitblt operation.
>>>>>>>               
>>>>> Seemed
>>>>>           
>>>>>>> like kind of a hack, and I didn't really expect it to work...  Do I
>>>>>>>               
>>> need
>>>       
>>>>>>> other libraries along with the gdi32.dll.so ?
>>>>>>>
>>>>>>> Any advice is appreciated.  Thanks.
>>>>>>>
>>>>>>> Eric Morgan
>>>>>>> Renegade Geophysics
>>>>>>> 303-661-0400, x2
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> Mono-list maillist  -  Mono-list at lists.ximian.com
>>>>>>> http://lists.ximian.com/mailman/listinfo/mono-list
>>>>>>>
>>>>>>>
>>>>>>>               
>>>>>>             
>>>>> _______________________________________________
>>>>> Mono-list maillist  -  Mono-list at lists.ximian.com
>>>>> http://lists.ximian.com/mailman/listinfo/mono-list
>>>>>
>>>>>
>>>>>           
>>>>         
>>> _______________________________________________
>>> Mono-list maillist  -  Mono-list at lists.ximian.com
>>> http://lists.ximian.com/mailman/listinfo/mono-list
>>>
>>>
>>>       
>> _______________________________________________
>> Mono-list maillist  -  Mono-list at lists.ximian.com
>> http://lists.ximian.com/mailman/listinfo/mono-list
>>     
>
> _______________________________________________
> Mono-list maillist  -  Mono-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
>
>
>   


More information about the Mono-list mailing list