Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. BitBlt performance in C#

BitBlt performance in C#

Scheduled Pinned Locked Moved C#
graphicscsharpperformancequestion
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    CyberKewl
    wrote on last edited by
    #1

    I'm using the following code to capture a screenshot : Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics gr1 = Graphics.FromImage(myImage); IntPtr dc1 = gr1.GetHdc(); IntPtr dc2 = GetDC(GetDesktopWindow()); BitBlt(dc1, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc2, 0, 0, 13369376); gr1.ReleaseHdc(dc1); GC.Collect(); return myImage; I'm trying to capture a screenshot of the entire desktop and transferring it to a remote PC (to create a program like PcAnywhere). The thing is, i set my screenshot timer to something like 450 ms and on my machine (Athlon XP 2000+), it uses up around 30% of the CPU power. However, if i test it on my old P3-700 Mhz machine, the CPU utilisation is very high, ranging between 75-90%. Is there any way to reduce the CPU utilisation (maybe like reducing the color depth of the image? but how)?

    J 1 Reply Last reply
    0
    • C CyberKewl

      I'm using the following code to capture a screenshot : Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics gr1 = Graphics.FromImage(myImage); IntPtr dc1 = gr1.GetHdc(); IntPtr dc2 = GetDC(GetDesktopWindow()); BitBlt(dc1, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc2, 0, 0, 13369376); gr1.ReleaseHdc(dc1); GC.Collect(); return myImage; I'm trying to capture a screenshot of the entire desktop and transferring it to a remote PC (to create a program like PcAnywhere). The thing is, i set my screenshot timer to something like 450 ms and on my machine (Athlon XP 2000+), it uses up around 30% of the CPU power. However, if i test it on my old P3-700 Mhz machine, the CPU utilisation is very high, ranging between 75-90%. Is there any way to reduce the CPU utilisation (maybe like reducing the color depth of the image? but how)?

      J Offline
      J Offline
      J Dunlap
      wrote on last edited by
      #2

      You should be releasing the DC you get with GetDC(), using ReleaseDC(), and if you aren't going to be using gr1 anymore, you should call Dispose() on it. What's making it slow is probably the transfer, not the capturing. I don't know if this will make it faster, or slower, but you could make a new Bitmap with a lower color depth, create a Graphics from it, and use Graphics.DrawImage() to draw the image onto the new Bitmap.

      "Blessed are the peacemakers, for they shall be called sons of God." - Jesus
      "You must be the change you wish to see in the world." - Mahatma Gandhi

      C 1 Reply Last reply
      0
      • J J Dunlap

        You should be releasing the DC you get with GetDC(), using ReleaseDC(), and if you aren't going to be using gr1 anymore, you should call Dispose() on it. What's making it slow is probably the transfer, not the capturing. I don't know if this will make it faster, or slower, but you could make a new Bitmap with a lower color depth, create a Graphics from it, and use Graphics.DrawImage() to draw the image onto the new Bitmap.

        "Blessed are the peacemakers, for they shall be called sons of God." - Jesus
        "You must be the change you wish to see in the world." - Mahatma Gandhi

        C Offline
        C Offline
        CyberKewl
        wrote on last edited by
        #3

        No, that doesn't make much difference. The code is now : Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics gr1 = Graphics.FromImage(myImage); IntPtr dc1 = gr1.GetHdc(); IntPtr dc2 = GetDC(GetDesktopWindow()); BitBlt(dc1, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc2, 0, 0, 13369376); gr1.ReleaseHdc(dc1); ReleaseDC(GetDesktopWindow(), dc2); GC.Collect(); return myImage; I fail to mention earlier that i am utilising a savejpgwithcompression function and after some checking, it appears that it is the cause of the problem. It could be the compression part, but it is essential to make the file size smaller. Here's the code : private void SaveJPGWithCompressionSetting( Image image, string szFileName, long lCompression ) { EncoderParameters eps = new EncoderParameters(1); eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, lCompression ); ImageCodecInfo ici = GetEncoderInfo("image/jpeg"); image.Save( szFileName, ici, eps ); } private ImageCodecInfo GetEncoderInfo(string mimeType) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); foreach (ImageCodecInfo codec in codecs) { if (codec.MimeType == mimeType){return codec;} } return null; }

        I 1 Reply Last reply
        0
        • C CyberKewl

          No, that doesn't make much difference. The code is now : Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics gr1 = Graphics.FromImage(myImage); IntPtr dc1 = gr1.GetHdc(); IntPtr dc2 = GetDC(GetDesktopWindow()); BitBlt(dc1, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc2, 0, 0, 13369376); gr1.ReleaseHdc(dc1); ReleaseDC(GetDesktopWindow(), dc2); GC.Collect(); return myImage; I fail to mention earlier that i am utilising a savejpgwithcompression function and after some checking, it appears that it is the cause of the problem. It could be the compression part, but it is essential to make the file size smaller. Here's the code : private void SaveJPGWithCompressionSetting( Image image, string szFileName, long lCompression ) { EncoderParameters eps = new EncoderParameters(1); eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, lCompression ); ImageCodecInfo ici = GetEncoderInfo("image/jpeg"); image.Save( szFileName, ici, eps ); } private ImageCodecInfo GetEncoderInfo(string mimeType) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); foreach (ImageCodecInfo codec in codecs) { if (codec.MimeType == mimeType){return codec;} } return null; }

          I Offline
          I Offline
          Ista
          wrote on last edited by
          #4

          Well your first problem BitBlt is the slowest drawing technique. DirectX has BitBltFast or FastBitBlt which is twice as fast. If your trying to accomplish fast rasterization your first problem is using the GDI. You should really use directX fucntionsin the framework or even just write c++ blocks in your cde and access the directx directly. If possible create pages and store the bitmap data within the pages then show them at times needed check out gamedev.net for a lot of pointers on graphics. nick I'm not an expert yet, but I play one at work. Yeah and here too.

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups