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
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. Graphics
  4. PictureBox using too much memory

PictureBox using too much memory

Scheduled Pinned Locked Moved Graphics
csharpgraphicsperformancehelptutorial
13 Posts 3 Posters 55 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.
  • G Offline
    G Offline
    gembob
    wrote on last edited by
    #1

    Hi, I have a windows CE device for which I am wrinting a C# .Net CF 2.0 application. This device has an inclinometer chip connected to it, which reads the angles my device is at, and sends me the X and Y tilt values of the inclinometer. Depending on those values, I want to display a picture. (.png). For now now I'm just using the X value (tiltX global variable) The image is being updated every 150ms So for a prototype I've being doing the following: //TiltX is being passed in to RotateGauge as an Int. private void RotateGauge(int side) { if (side > -5 & side < 5) { string number = Convert.ToString(side); Stream sidePic = _assembly.GetManifestResourceStream("Rotate_Test.images.gauge.sideTilt" + (number) + ".png"); Bitmap bmp = new Bitmap(sidePic); Graphics g = CreateGraphics(); g.DrawImage(bmp, 42,116); //draw image bmp.Dispose(); sidePic.Close(); g.Dispose(); } } The above function RotateGauge() gets called from a timer. (interival 150ms) The problem is its using up a lot of memory. I don't think I'm properly disposing of things. Any suggestions how to : Efficiently rewrite the above code so when something gets created on a timer_tick it also gets disposed of properly

    L 1 Reply Last reply
    0
    • G gembob

      Hi, I have a windows CE device for which I am wrinting a C# .Net CF 2.0 application. This device has an inclinometer chip connected to it, which reads the angles my device is at, and sends me the X and Y tilt values of the inclinometer. Depending on those values, I want to display a picture. (.png). For now now I'm just using the X value (tiltX global variable) The image is being updated every 150ms So for a prototype I've being doing the following: //TiltX is being passed in to RotateGauge as an Int. private void RotateGauge(int side) { if (side > -5 & side < 5) { string number = Convert.ToString(side); Stream sidePic = _assembly.GetManifestResourceStream("Rotate_Test.images.gauge.sideTilt" + (number) + ".png"); Bitmap bmp = new Bitmap(sidePic); Graphics g = CreateGraphics(); g.DrawImage(bmp, 42,116); //draw image bmp.Dispose(); sidePic.Close(); g.Dispose(); } } The above function RotateGauge() gets called from a timer. (interival 150ms) The problem is its using up a lot of memory. I don't think I'm properly disposing of things. Any suggestions how to : Efficiently rewrite the above code so when something gets created on a timer_tick it also gets disposed of properly

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi, I don't see anything wrong with your object disposal, so I expect the garbage collector will clean up memory if need be. However I think you are spending way too much CPU power to achieve your goals. This is how I would do it: - replace the PictureBox by a simple Panel (or an inherited Panel that sets its ControlStyles to double-buffered for better graphics); - do the drawing in the Panel's OnPaint method, based on a single class member (int side); it gives you a Graphics for free (which you should not dispose!); - when you want to change the gauge, change the variable (side) and call your Panel's Invalidate method If you only have a dozen PNG images, you may even consider keeping them alive in memory all the time. :)

      Luc Pattyn [Forum Guidelines] [My Articles]


      Happy 2008!


      P G 2 Replies Last reply
      0
      • L Luc Pattyn

        Hi, I don't see anything wrong with your object disposal, so I expect the garbage collector will clean up memory if need be. However I think you are spending way too much CPU power to achieve your goals. This is how I would do it: - replace the PictureBox by a simple Panel (or an inherited Panel that sets its ControlStyles to double-buffered for better graphics); - do the drawing in the Panel's OnPaint method, based on a single class member (int side); it gives you a Graphics for free (which you should not dispose!); - when you want to change the gauge, change the variable (side) and call your Panel's Invalidate method If you only have a dozen PNG images, you may even consider keeping them alive in memory all the time. :)

        Luc Pattyn [Forum Guidelines] [My Articles]


        Happy 2008!


        P Offline
        P Offline
        Pete OHanlon
        wrote on last edited by
        #3

        Hey Luc. Congratulations on your MVP status. It's well deserved.

        Deja View - the feeling that you've seen this post before.

        My blog | My articles

        L 1 Reply Last reply
        0
        • P Pete OHanlon

          Hey Luc. Congratulations on your MVP status. It's well deserved.

          Deja View - the feeling that you've seen this post before.

          My blog | My articles

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          Hi Pete, thanks. Congrats to you too. I see several of us have reached the next station. ;P Mine came as a surprise, wasn't aware how many there would be, but even then...

          Luc Pattyn [Forum Guidelines] [My Articles]


          Happy 2008!


          P 1 Reply Last reply
          0
          • L Luc Pattyn

            Hi Pete, thanks. Congrats to you too. I see several of us have reached the next station. ;P Mine came as a surprise, wasn't aware how many there would be, but even then...

            Luc Pattyn [Forum Guidelines] [My Articles]


            Happy 2008!


            P Offline
            P Offline
            Pete OHanlon
            wrote on last edited by
            #5

            Luc Pattyn wrote:

            Mine came as a surprise

            Not to me. I had good money riding on you getting it. It's nice not to have the yokel icon beside the names now. I like being a yellow diamond. :-D

            Deja View - the feeling that you've seen this post before.

            My blog | My articles

            L 2 Replies Last reply
            0
            • P Pete OHanlon

              Luc Pattyn wrote:

              Mine came as a surprise

              Not to me. I had good money riding on you getting it. It's nice not to have the yokel icon beside the names now. I like being a yellow diamond. :-D

              Deja View - the feeling that you've seen this post before.

              My blog | My articles

              L Offline
              L Offline
              Luc Pattyn
              wrote on last edited by
              #6

              Pete O'Hanlon wrote:

              I had good money riding on you getting it.

              Who is taking those bets? is that what is going on in the dark hours at the lounge?

              Pete O'Hanlon wrote:

              It's nice not to have the yokel icon beside the names now. I like being a yellow diamond

              Had to look that up, but I fully agree; it was/is not the nicest icon available. BTW I think the golden diamond writer personality title I currently carry is the one I like most (prolific fixture sounds really weird to me, I'll try to avoid it). :)

              Luc Pattyn [Forum Guidelines] [My Articles]


              Happy 2008!


              1 Reply Last reply
              0
              • P Pete OHanlon

                Luc Pattyn wrote:

                Mine came as a surprise

                Not to me. I had good money riding on you getting it. It's nice not to have the yokel icon beside the names now. I like being a yellow diamond. :-D

                Deja View - the feeling that you've seen this post before.

                My blog | My articles

                L Offline
                L Offline
                Luc Pattyn
                wrote on last edited by
                #7

                forgot to mention, I did notice how you skilfully reverted the topic to make it really fit the graphics forum. A worthy diamond. ;P

                Luc Pattyn [Forum Guidelines] [My Articles]


                Happy 2008!


                1 Reply Last reply
                0
                • L Luc Pattyn

                  Hi, I don't see anything wrong with your object disposal, so I expect the garbage collector will clean up memory if need be. However I think you are spending way too much CPU power to achieve your goals. This is how I would do it: - replace the PictureBox by a simple Panel (or an inherited Panel that sets its ControlStyles to double-buffered for better graphics); - do the drawing in the Panel's OnPaint method, based on a single class member (int side); it gives you a Graphics for free (which you should not dispose!); - when you want to change the gauge, change the variable (side) and call your Panel's Invalidate method If you only have a dozen PNG images, you may even consider keeping them alive in memory all the time. :)

                  Luc Pattyn [Forum Guidelines] [My Articles]


                  Happy 2008!


                  G Offline
                  G Offline
                  gembob
                  wrote on last edited by
                  #8

                  Hi Luc, Thanks for your reply. I got overly excited when I saw 6 replies to my post :) as i've spent a lot of time trying to figure this out. I attempted what you suggested, however the Compact Framework has me limited in what I can do. The line of code I hoped to use for drawing in the panel is g = panel1.CreateGraphics(); however, CreateGraphics is not availble to my panel in the CF. I'll keep looking, I'm very new to c# (programming in general) so there may be a solution for me somewhere. Regards Gemma

                  L 1 Reply Last reply
                  0
                  • G gembob

                    Hi Luc, Thanks for your reply. I got overly excited when I saw 6 replies to my post :) as i've spent a lot of time trying to figure this out. I attempted what you suggested, however the Compact Framework has me limited in what I can do. The line of code I hoped to use for drawing in the panel is g = panel1.CreateGraphics(); however, CreateGraphics is not availble to my panel in the CF. I'll keep looking, I'm very new to c# (programming in general) so there may be a solution for me somewhere. Regards Gemma

                    L Offline
                    L Offline
                    Luc Pattyn
                    wrote on last edited by
                    #9

                    Hi, maybe you should read my original reply once more. The whole point was NOT to use CreateGraphics, but OnPaint() instead. :)

                    Luc Pattyn [Forum Guidelines] [My Articles]


                    Happy 2008!


                    G 1 Reply Last reply
                    0
                    • L Luc Pattyn

                      Hi, maybe you should read my original reply once more. The whole point was NOT to use CreateGraphics, but OnPaint() instead. :)

                      Luc Pattyn [Forum Guidelines] [My Articles]


                      Happy 2008!


                      G Offline
                      G Offline
                      gembob
                      wrote on last edited by
                      #10

                      Hi Luc, I've since gone off and done some reading on .net CF graphics, in the process I came across some code which I've implemented into my project. private Bitmap LoadBitmapResource(string strName) { Assembly assembly = Assembly.GetExecutingAssembly(); string strRes = "Rotate_Test.images.gauge." + strName; Stream stream = assembly.GetManifestResourceStream(strRes); Bitmap bmp = null; try { bmp = new Bitmap(stream); } catch { } stream.Close(); return bmp; } private void DisposeBitmap(ref Bitmap bmp) { if (bmp != null) { bmp.Dispose(); } bmp = null; } In the Panel Paint method I have the following. private void panel1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; DisposeBitmap(ref bmpDraw); //Get the Bitmap to draw bmpDraw = LoadBitmapResource("backTilt" + (strResNum) + ".bmp"); g.DrawImage(bmpDraw, 10, 10); } The above is still using up memory for every image which is displayed, it seems like nothing is being freed up. I haven't started looking at double buffering as for now I'm more concerned with relasing the memory used. Thanks for your suggestion regards Gemma

                      L 1 Reply Last reply
                      0
                      • G gembob

                        Hi Luc, I've since gone off and done some reading on .net CF graphics, in the process I came across some code which I've implemented into my project. private Bitmap LoadBitmapResource(string strName) { Assembly assembly = Assembly.GetExecutingAssembly(); string strRes = "Rotate_Test.images.gauge." + strName; Stream stream = assembly.GetManifestResourceStream(strRes); Bitmap bmp = null; try { bmp = new Bitmap(stream); } catch { } stream.Close(); return bmp; } private void DisposeBitmap(ref Bitmap bmp) { if (bmp != null) { bmp.Dispose(); } bmp = null; } In the Panel Paint method I have the following. private void panel1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; DisposeBitmap(ref bmpDraw); //Get the Bitmap to draw bmpDraw = LoadBitmapResource("backTilt" + (strResNum) + ".bmp"); g.DrawImage(bmpDraw, 10, 10); } The above is still using up memory for every image which is displayed, it seems like nothing is being freed up. I haven't started looking at double buffering as for now I'm more concerned with relasing the memory used. Thanks for your suggestion regards Gemma

                        L Offline
                        L Offline
                        Luc Pattyn
                        wrote on last edited by
                        #11

                        Hi Gemma, 1. your code looks fine to me, with one comment: if every OnPaint does a Disposeand a Load, and assuming bmpDraw is not used elsewhere, why not do it after the DrawImage (hence: load,draw,dispose)? 2. calling Dispose is good, it frees unmanaged resources immediately (if any), and marks managed objects for garbage collection, which only occurs when the garbage collector feels a need (i.e. when memory is low when a new object is being created, say in a "new" statement). So it is not abnormal to see a high memory usage, as long as it comes down every so often, and does not lead to an "out of memory" situation. As a test, you could add a big object to your main class (to occupy memory) and see how well the app does under those circumstances, so add a line such as: private byte[] dummyBytes=new byte[1024*1024]; // permanently occupies 1MB 3. If you are still not satisfied, here are some questions: - what is it that makes you worry? - how many images are there? - how big is each image (in pixels and in file size)? :)

                        Luc Pattyn [Forum Guidelines] [My Articles]


                        This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


                        G 1 Reply Last reply
                        0
                        • L Luc Pattyn

                          Hi Gemma, 1. your code looks fine to me, with one comment: if every OnPaint does a Disposeand a Load, and assuming bmpDraw is not used elsewhere, why not do it after the DrawImage (hence: load,draw,dispose)? 2. calling Dispose is good, it frees unmanaged resources immediately (if any), and marks managed objects for garbage collection, which only occurs when the garbage collector feels a need (i.e. when memory is low when a new object is being created, say in a "new" statement). So it is not abnormal to see a high memory usage, as long as it comes down every so often, and does not lead to an "out of memory" situation. As a test, you could add a big object to your main class (to occupy memory) and see how well the app does under those circumstances, so add a line such as: private byte[] dummyBytes=new byte[1024*1024]; // permanently occupies 1MB 3. If you are still not satisfied, here are some questions: - what is it that makes you worry? - how many images are there? - how big is each image (in pixels and in file size)? :)

                          Luc Pattyn [Forum Guidelines] [My Articles]


                          This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


                          G Offline
                          G Offline
                          gembob
                          wrote on last edited by
                          #12

                          Thanks for the useful information and checking my code for me. I've no peers to learn from or show my code to, (one man show here) so its great to get advice.

                          L 1 Reply Last reply
                          0
                          • G gembob

                            Thanks for the useful information and checking my code for me. I've no peers to learn from or show my code to, (one man show here) so its great to get advice.

                            L Offline
                            L Offline
                            Luc Pattyn
                            wrote on last edited by
                            #13

                            You're welcome. :)

                            Luc Pattyn [Forum Guidelines] [My Articles]


                            This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.


                            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