Results 1 to 6 of 6

Thread: Set pixel in some container?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Jul 1999
    Location
    Huntingdon Valley, PA 19006
    Posts
    1,151

    Set pixel in some container?

    VB 6.0 had a Set Pixel function, which is not available in VB.net. Help suggested using a draw ellipse function with parameters specifying a circle one pixel in diameter.

    The above is painfully slow.

    I have been drawing graphics in a Bit Map using a Set Pixel function & then copying the entire graphic from Bit Map to a Picture Box. This results in nothing seeming to happen for several seconds & then the entire graphic is displayed in the Picture Box.

    The above does the job, but it would be nice to display the graphic as it is being generated pixel by pixel, which was possible using VB 6.0

    Might there be a Windows 7 API which would set a pixel? Might Microsoft be considering a Set Pixel function for Picture Box graphics?
    Live long & prosper.

    The Dinosaur from prehistoric era prior to computers.

    Eschew obfuscation!
    If a billion people believe a foolish idea, it is still a foolish idea!
    VB.net 2010 Express
    64Bit & 32Bit Windows 7 & Windows XP. I run 4 operating systems on a single PC.

  2. #2
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Set pixel in some container?

    SetPixel is dreadfully slow. I wont recommend at all...even if you wanted to change 10 pixels. Use the Bitmap class's LockBits method instead to get the bitmap's bits and manipulated them directly.

  3. #3
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Set pixel in some container?

    Quote Originally Posted by Guv View Post
    VB 6.0 had a Set Pixel function, which is not available in VB.net. Help suggested using a draw ellipse function with parameters specifying a circle one pixel in diameter.

    The above is painfully slow.

    I have been drawing graphics in a Bit Map using a Set Pixel function & then copying the entire graphic from Bit Map to a Picture Box. This results in nothing seeming to happen for several seconds & then the entire graphic is displayed in the Picture Box.

    The above does the job, but it would be nice to display the graphic as it is being generated pixel by pixel, which was possible using VB 6.0

    Might there be a Windows 7 API which would set a pixel? Might Microsoft be considering a Set Pixel function for Picture Box graphics?
    The Bitmap.SetPixel method makes it unnecessary to have a similar function for a picture box. You can set the pixels in a bitmap and then paint it in the picture box. There are two main ways to do that: use the bitmap as the PictureBox.Image (or BackgroundImage), or use Graphics.DrawImage in its Paint event sub. Clearly you have been trying on of these but a delay of a few seconds suggests you might not be going about it in an efficient way. It would help to see the code you are using for that.

    To show a developing image at animation speed, you should Invalidate/Update or Refresh the picture box at clocked intervals. In other words use a timer set to about 15 to 50 ms to refresh the picture box. If the picture box is large, you can improve efficiency by invalidating only the affected rectangle of the picture box and then updating it.

    SetBitmap is itself pretty slow if you want to change more than just a few pixels, so it could also be the culprit of the slowness. It can be speeded up vastly by using the Bitmap.Lockbits method (as much as 100x if you do it optimally). For a relatively easy way to take advantage of that, see the Rapid Pixel Processing link in my signature.

    If you want more details or a code example, it would help if you post the code you are using at present. Please also indicate the size of the bitmap and the picture box.

    BB

  4. #4

    Thread Starter
    Frenzied Member
    Join Date
    Jul 1999
    Location
    Huntingdon Valley, PA 19006
    Posts
    1,151

    Re: Set pixel in some container?

    Boops Boops: Thanx for your advice. I have copied the code you indicated, scanned it briefly, & will study it later.

    I must update my signature. I amnow running 64Bit Windows 7 & using VB.net 2010 Express. I wish I could afford a professional version.

    My current VB.net program generates Fractal Graphics. It currently seems fast enough as is.

    I was hoping for fast code which would display a graphic Pixel by Pixel as it is being generated, which is what a VB 6.0 program did for me circa 10 years ago.

    The details of the code would not be of interest. The following summarizes the timing & some alternative drawing methods. I do not have a stop watch, so the times using a digital stop watch are not accurate.

    PixFractal (Picture Box) & FractalMap (Bitmap) are 1168*1168, about 1.364 million pixels, with the program using For-Next Loops.

    pixFractal.CreateGraphics.DrawEllipse(PixelPen, PixelX, PixelY, 1, 1) took 4.25 minutes to draw a Cube Root Fractal directly in the Picture Box. This was suggested by some article as a replacement for the VB 6.0 Set Pixel syntax. This speed was intolerable.

    FractalMap.SetPixel(PixelX, PixelY, PixelPen.Color) took 4-6 seconds. When the graphic was drawn, pixFractal.Image = FractalMap was used to put it into the Picture Box. This is used in the current version of the program & is fast enough to suit me.

    The code required to determine Pixel Color uses simple calculus (Newton successive approximations). With the Pixel setting syntax commented out, the program took 4-6 seconds.
    The time required to actually Set Pixels in the Bitmap is negligible.

    I have been running the program using the IDE Debug Mode. Does IDE Debug Mode add much runtime to a project?

    BTW: The first mainframe (circa 1951) I wrote programs for required milliseconds for a machine language add instruction. That mainframe could not do the above job in a month. The speed of my PC still startles me. It’s computational speed beats the last mainframe I used in 1998.
    Live long & prosper.

    The Dinosaur from prehistoric era prior to computers.

    Eschew obfuscation!
    If a billion people believe a foolish idea, it is still a foolish idea!
    VB.net 2010 Express
    64Bit & 32Bit Windows 7 & Windows XP. I run 4 operating systems on a single PC.

  5. #5
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Set pixel in some container?

    Quote Originally Posted by Guv View Post
    Boops Boops: Thanx for your advice. I have copied the code you indicated, scanned it briefly, & will study it later.

    I must update my signature. I amnow running 64Bit Windows 7 & using VB.net 2010 Express. I wish I could afford a professional version.
    If you work solo, the advantages of the prof versions over Express are surprisingly few.
    My current VB.net program generates Fractal Graphics. It currently seems fast enough as is.

    I was hoping for fast code which would display a graphic Pixel by Pixel as it is being generated, which is what a VB 6.0 program did for me circa 10 years ago.

    The details of the code would not be of interest. The following summarizes the timing & some alternative drawing methods. I do not have a stop watch, so the times using a digital stop watch are not accurate.

    [INDENT]PixFractal (Picture Box) & FractalMap (Bitmap) are 1168*1168, about 1.364 million pixels, with the program using For-Next Loops.

    pixFractal.CreateGraphics.DrawEllipse(PixelPen, PixelX, PixelY, 1, 1)
    took 4.25 minutes to draw a Cube Root Fractal directly in the Picture Box. This was suggested by some article as a replacement for the VB 6.0 Set Pixel syntax. This speed was intolerable.
    Whoever wrote that had a spoonful of lard for a brain. Maybe you are already using the simple and very accurate (approx 250 nanoseconds) Stopwatch class for code timing. The difficulty is knowing exactly what you are timing, especially in a managed environment with JIT compilation, garbage collection etc.
    FractalMap.SetPixel(PixelX, PixelY, PixelPen.Color) took 4-6 seconds. When the graphic was drawn, pixFractal.Image = FractalMap was used to put it into the Picture Box. This is used in the current version of the program & is fast enough to suit me.

    The code required to determine Pixel Color uses simple calculus (Newton successive approximations). With the Pixel setting syntax commented out, the program took 4-6 seconds.

    The time required to actually Set Pixels in the Bitmap is negligible.
    Here's some code to illustrate the use Invalidate/Update to animate the development of a bitmap. It fills the picturebox with lines of random pixels from top to bottom.
    vb Code:
    1. Private rnd As New Random
    2. Private bmp As Bitmap
    3. Private Sub makeimage()
    4.     bmp = New Bitmap(1168, 1168)
    5.     PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
    6.     PictureBox1.Image = bmp
    7.  
    8.     For y As Integer = 0 To 1167
    9.         For x As Integer = 0 To 1167
    10.             Dim r As Integer = rnd.Next(0, 256)
    11.             Dim g As Integer = rnd.Next(0, 256)
    12.             Dim b As Integer = rnd.Next(0, 256)
    13.             Dim color As Color = color.FromArgb(r, g, b)
    14.             bmp.SetPixel(x, y, color)
    15.             PictureBox1.Invalidate(New Rectangle(x, y, 1, 1))
    16.             PictureBox1.Update()
    17.         Next
    18.     Next
    19. End Sub
    However, updating the PictureBox one pixel at a time is extremely slow (VB6 probably has an advantage there). You could do a timed update like this (replacing line 16 above):
    Code:
    If DateTime.Now.Millisecond Mod 20 = 0 Then PictureBox1.Update()
    although in this instance it looks much nicer to update the image line by line:
    Code:
    If x = 1167 Then PictureBox1.Update()
    Maybe you could try introducing Invalidate + Update at an appropriate point in your own code. However, it would be a better design to separate the number crunching from the UI by putting it in a separate thread e.g. using a BackgroundWorker, with a timer to trigger updating of the UI.

    I have been running the program using the IDE Debug Mode. Does IDE Debug Mode add much runtime to a project?
    Sometimes. You can go to Project Properties/Compiler/Advanced and tick "Ignore integer overflow checks" and "Use compiler optimization" to see if it makes any difference. You can also try running without the IDE -- Ctrl-F5 in Visual Studio. There might be other ways to optimize your own code (among other things using LockBits instead of SetPixel).

    BB

  6. #6

    Thread Starter
    Frenzied Member
    Join Date
    Jul 1999
    Location
    Huntingdon Valley, PA 19006
    Posts
    1,151

    Re: Set pixel in some container?

    Boops Boops: Thanx much for the very useful information in your posts.

    Will make use of it in my current & future projects. I copied from your posts & from the Linked-to Sites indicated in your signature.

    BTW: I use Gadwin Systems PrintScreen utility to capture data from Web pages. Once installed it is activated via the PrintScreen Key.

    I have it set up with options to use Click & Drag specification of a rectangular area of interest. The area is copied as a .bmp to a default folder & to the clipboard.
    Live long & prosper.

    The Dinosaur from prehistoric era prior to computers.

    Eschew obfuscation!
    If a billion people believe a foolish idea, it is still a foolish idea!
    VB.net 2010 Express
    64Bit & 32Bit Windows 7 & Windows XP. I run 4 operating systems on a single PC.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width