- Tanner Helland (dot) Com - http://www.tannerhelland.com -
VB Graphics Programming: Part 1 (Pure VB)
Posted By Tanner On June 17, 2008 @ 8:31 pm In Graphics Code,Programming,Tutorials | 12 Comments
Pure VB Pixel Routines
First, let’s discuss the basics of per-pixel graphics programming using only built-in Visual Basic functions. I recommend that even hardened VB veterans glance through this document, as it provides the foundation for the advanced graphics principles discussed in the next three tutorials. We will discuss the only VB per-pixel graphics functions (Point and PSet), and after this is done you may know a lot more than you ever wanted to about VB graphics… :) *hehe*
Most of you have probably heard of the “horrible twins of PSet and Point”*. These two routines are usually the first per-pixel methods introduced to VB programmers (since they come included as part of the language), but – perhaps inevitably – they are also the slowest way to do things. Avoid ever using these routines for per-pixel image processing (though they do have some uses in non-pixel-sized work). I include them here only for completeness; I would never recommend using them in an actual image processing program because they are so extremely slow.
Why are they so slow? We’ll discuss that later, after we’ve looked at their syntax.
I – Getting the Color of an Individual Pixel
You can use the Point event in VB to get the color of a specified pixel. The format is as follows:
Dim Color as Long
Color = PictureBox.Point(x,y)
PictureBox is the name of the picture box or form you want to retrieve the pixel from, and (x,y) are the pixel’s coordinates.
For example, if you wanted to get a color from spot (35, 42) of picture box “Picture1″, you would use the following:
Color = Picture1.Point(35,42)
It doesn’t get much simpler than that, folks.
So now the question is “what do I do once I’ve gotten the color?” After all, it comes in Long type, which is some strange number from -2 billion to +2 billion…and that really doesn’t lend itself to easily adjusting the color of that pixel.
Thus the challenge is figuring out how to change one 4-byte number into three 1-byte numbers (red, green, and blue).
While this may sound easy, the theory behind doing this requires some knowledge of binary encoding…which is far too large a topic to be covered here. Luckily for you, here are three functions that will automatically do RGB color extraction for you:
Public Function ExtractR(ByVal CurrentColor As Long) As Byte
ExtractR = CurrentColor And 255
End Function
Public Function ExtractG(ByVal CurrentColor As Long) As Byte
ExtractG = (CurrentColor \ 256) And 255
End Function
Public Function ExtractB(ByVal CurrentColor As Long) As Byte
ExtractB = (CurrentColor \ 65536) And 255
End Function
To utilize these functions, use the following syntax:
Dim R as Byte, G as Byte, B as Byte
Dim Color as Long
Color = PictureBox.Point(0, 0)
R = ExtractR(Color)
G = ExtractG(Color)
B = ExtractB(Color)
Pretty neat, eh?
This is the first method we’ll use for getting a pixel’s data and breaking it down into its red, green, and blue components. Now let’s quickly mention how to set this data back into a picture box.
II – Setting the Color of an Individual Pixel
Setting a pixel’s color is almost identical to getting its color. You use the VB event “PSet,” which stands for “Pixel Set.”
PictureBox.PSet (x,y), Color
Again, PictureBox is the name of the picture box or form you want to set the pixel to and (x,y) are the pixel’s coordinates. The only difference here is that we also include the color that we want to set. So, using the example above, if you wanted to set a color to pixel (35, 42) of picture box “Picture1″ you would use the following:
Picture1.PSet (35,42), Color
It is worth noting that Color is of type Long, which creates the same problem we discussed above – how to change three separate red/green/blue values into a single 4-byte number. Fortunately, VB has a built-in command called RGB() that does this conversion for us. To illustrate it’s use, let’s use the same example saying that you want to change the color of the pixel at (35,42) to pure red:
Picture1.PSet (35,42), RGB(255, 0, 0)
The first RGB parameter is red, then green, last blue, so RGB(255,0,0) will set the color to pure red. Easy!
III – Using Point and PSet to Edit an Image
First, a little disclaimer: entire books have been written on the theories behind GP and there are entire programming disciplines whose job is nothing but optimizing graphics routines. So, while what I’m about to show you in code is a nice method, be advised that GP is an extremely complicated field and to truly succeed in it you must be willing to do a little research. I have chosen a well-optimized and very standard method for my sample programs because it is easy to understand while still offering good results. But, for this first tutorial, don’t be disappointed if the results aren’t particularly incredible or lightning-fast. That’s what the next three tutorials are for!
The code in this .zip file will demonstrate how to change the brightness of an image using a standard linear brightness algorithm. The code is simple and well-commented. Read through the comments and make sure that you understand how everything works.
IV – Why are Point and PSet So Slow?
If you’ve tried out the sample code, you’re probably not impressed…and rightfully so! Point and PSet – though easy to use – are extremely slow. Can you imagine trying to work with images 4 or 5 times the size of the demo one? Not so cool.
So why are these two functions SO slow? To illustrate it, let’s follow the path your computer takes for changing the color of a single pixel using Point and PSet as you just saw done in the sample program. (Author’s Note: I base these conclusions on general programming knowledge, not known facts; so while I’m pretty sure that this explanation is accurate, I could be wrong on some of the details. I invite and encourage input on making this section 100% accurate.)
Steps 1, 2, 5, 7, and 9 are what’s slowing down your PSet/Point-based graphics program. Visual Basic is very nice in that it does almost all of your error checking for you, but there is a definite speed trade-off. In other programming languages and per-pixel routines, many of these error checking steps are removed – which is one of the reasons why other languages and functions are generally faster but more dangerous to use. In the next three tutorials we will discuss alternate methods of doing graphics that cut out some of these “speed killer” steps.
V – Conclusion
Hope that all made sense to you! Does it feel good knowing you can now program any graphics routine using nothing but VB? Hope it does – but don’t get too comfortable yet.
To be totally honest, I hope that you completely forget that PSet and Point even exist – at least as far as per-pixel image processing is concerned – after reading the next three tutorials. Both are extremely slow and… well, just bad programming for image processing. VB6 is good for a lot of things, but its pixel interfacing is a total joke.
Thankfully, there are three more tutorials that will show you better, faster ways to do graphics programming – but at least you now know how to use PSet and Point if the need ever arises.
CONTINUE TO “BASIC API PIXEL ROUTINES” [2]
*As quoted by Matt Hart, the legendary VB programmer
Article printed from Tanner Helland (dot) Com: http://www.tannerhelland.com
URL to article: http://www.tannerhelland.com/40/vb-graphics-programming-1/
URLs in this post:
[1] Download the PSet/Point example program: http://www.tannerhelland.com/code/VBGT_VB_example.zip
[2] CONTINUE TO “BASIC API PIXEL ROUTINES”: http://www.tannerhelland.com/41/vb-graphics-programming-2/
Click here to print.
All text copyright © 2008 Tanner Helland. To reduce paper and ink usage, all comments, images, and videos have been suppressed on this printing.