Bitmap


The Bitmap class represents an image defined by pixel data. You can use a Bitmap to create, load, modify, and save image data to sources that display pixel data such as screen objects (PictureBoxes, Forms, UserControls, and so on) and image files (BMP, GIF, JPEG, PNG, TIFF, and so on).

Many of the Bitmap class’s most useful properties and methods are inherited from the Image class. These include Height, HorizontalResolution, Palette, RawFormat, Size, Width, GetThumbnailImage, RotateFlip, and Save. See the section “Image” earlier in this chapter for information about those and other inherited properties and methods.

The following table describes some of the most useful methods that the Bitmap class adds to those inherited from the Image class.

Method

Purpose

FromHicon

This shared function loads a Bitmap image from a Windows icon handle. (An icon handle is a 32-bit integer that gives a value associated with the icon in the GDI environment. Windows uses the handle to refer to the icon when it needs to manipulate it. In the .NET environment, you generally work with Icon objects and don’t need to worry about icon handles. It’s useful to know about this method, however, in case you need to manipulate an icon loaded using older GDI routines).

FromResource

This shared function loads a Bitmap image from a Windows resource.

GetPixel

Returns a specified pixel’s Color.

LockBits

Locks the Bitmap class’s data in memory, so it cannot move until the program calls UnlockBits.

MakeTransparent

Makes all pixels with a specified color transparent by setting their alpha components to 0.

SetPixel

Sets a specified pixel’s Color value.

SetResolution

Sets the Bitmap class’s horizontal and vertical resolution in dots per inch (DPI).

UnlockBits

Unlocks the Bitmap class’s data in memory so the system can relocate it if necessary.

For most applications, the GetPixel and SetPixel methods provide adequate performance when manipulating pixels, but there is some overhead in moving through the different layers between the program’s code and the actual pixel data. For applications that work with very large images or that need to process pixel data on many images very quickly, performance may be an issue.

In cases where speed is an issue, you can access the pixel data more directly using so-called unsafe access. The program locks the Bitmap class’s data, reads and updates the pixel values, and then unlocks the data. See the section “Pixel-by-Pixel Operations” later in this chapter for more information and examples.

Loading Bitmaps

Loading a Bitmap from a file is simple. Simply pass the file’s name into the Bitmap class’s constructor. The following code loads the bitmap file whose name is stored in the variable file_name, and then displays it in the PictureBox control named picImage:

  Dim bm As New Bitmap(file_name) picImage.Image = bm 

After you have loaded a Bitmap, you can attach a Graphics object to it, draw on it, display it, and save the results in a new bitmap file. The following code loads the bitmap file, attaches a Graphics object to it, uses that object to draw an ellipse, and displays the result in the picImage control.

  Dim bm As New Bitmap(file_name) Using gr As Graphics = Graphics.FromImage(bm)     gr.DrawEllipse(Pens.White, 0, 0, bm.Width - 1, bm.Height - 1) End Using picImage.Image = bm 

Unfortunately, the Bitmap object holds some sort attachment to the bitmap file. If you try to delete the file while the program is running and still using the Bitmap, the operating system complains that the file is locked by another process. Similarly, if you open the file in a program such as Microsoft Paint, make some changes, and try to save the file, the operating system complains about a sharing violation.

To release the file for other programs to use, you must dispose of the Bitmap object that opened it. However, if you assign the Bitmap to a property (such as Image property of a PictureBox), the property keeps a reference to the Bitmap and will later generate an error when it tries to use the Bitmap that you have disposed.

One solution to this dilemma is to create a second Bitmap that is a copy of the first Bitmap, as shown in the following code. Then you can safely dispose of the first Bitmap. Because the second Bitmap was never associated with the bitmap file, the file is not locked.

  ' Load the bitmap file. Dim bm As New Bitmap(file_name) ' Make a copy. Dim new_bm As New Bitmap(bm) ' Dispose of the original Bitmap. bm.Dispose ' Draw on the new Bitmap and display the result. Using gr As Graphics = Graphics.FromImage(new_bm)     gr.DrawEllipse(Pens.White, 0, 0, new_bm.Width - 1, new_bm.Height - 1) End Using picImage.Image = new_bm 

Saving Bitmaps

You can use a Bitmap object’s Save method to save the bitmap into a file or data stream. To save the Bitmap into a file, the Save method’s first parameter should be the file’s name. If you provide only the file name, the Bitmap is saved in PNG format no matter what extension you give the file. If you save the file in PNG format but the file’s extension is something other than .PNG, such as .BMP or .GIF, you may become very confused later when Microsoft Paint refuses to open the file.

To save the Bitmap in some format other than PNG, pass the format as the Save method’s second parameter. To avoid confusion, you should give the file the appropriate extension. If you save a BMP file, give the file a .BMP extension.

The following code generates a 256 × 256 pixel bitmap from scratch and saves it in a JPEG file:

  ' Make a 256x256 pixel Bitmap. Dim bm As New Bitmap(256, 256) ' Draw on it. Using gr As Graphics = Graphics.FromImage(bm)     gr.Clear(Color.White)     gr.DrawEllipse(Pens.Red, 0, 0, bm.Width - 1, bm.Height - 1)     gr.DrawLine(Pens.Green, 0, 0, bm.Width - 1, bm.Height - 1)     gr.DrawLine(Pens.Blue, bm.Width - 1, 0, 0, bm.Height - 1) End Using ' Save the result as a JPEG file. bm.Save("C:\test.jpg", ImageFormat.Jpeg) 

The ImageFormat enumeration includes the formats Bmp, Emf, Exif, Guid, Icon, Jpeg, MemoryBmp, Png, Tiff, and Wmf.

If you save a Bitmap image in the Wmf (Windows metafile) or Emf (Enhanced metafile) format, the Save method creates a metafile that contains a bitmapped image. If you create a metafile by using a Metafile object, on the other hand, the result is a metafile that contains records that draw lines, curves, text, and so forth. The difference can have a couple of important consequences.

First, if the image is large, the bitmapped version may take up a lot more space than the version that records only drawing commands. It may also take a lot longer to draw a large bitmap than it would to draw a few circles and lines.

Second, you can transform a metafile that contains commands more readily than you can transform a metafile that contains a bitmap. If you enlarge a metafile containing commands, the result contains enlarged lines, curves, and other output. If you enlarge a metafile containing a bitmap, the result is a relatively blocky enlarged bitmap. Anti-aliasing may help a little, but the metafile containing drawing commands will produce a much better result.

On the other hand, not all programs understand all metafile commands. You may load a metafile containing drawing commands into another application and find that your ellipses and text don’t work. Although a metafile containing a bitmap won’t resize nicely, at least it should look similar to what you created.

See the section “Metafile Objects” later in this chapter for more information on metafiles.

Implementing AutoRedraw

In Visual Basic 6 and earlier versions, the Form and PictureBox objects had an AutoRedraw property. If you set this property to True, anything you drew on the object was automatically saved. If the object was later obscured and redrawn, the drawing was automatically restored.

This method required Visual Basic to allocate a chunk of internal memory to store the image, so it was not free. However, it could be a lot easier and faster than redrawing a complex image from scratch every time the drawing is exposed. For example, drawing a Mandelbrot set or other complex fractal may require hundreds or thousands of calculations per pixel in the image. Drawing a large image may take 10 or 20 seconds even on a relatively fast computer. Redrawing the image from scratch every time such a form was exposed would be impractical.

The bad news is that Visual Basic .NET has no AutoRedraw property. If you want similar functionality, you must implement it yourself. The good news is that Visual Basic .NET has a couple of controls that can display a persistent image, and they can do a lot of the work for you.

The Form object’s BackgroundImage property holds an image that covers the form’s background. If the image is too big to fit, it is cropped. If the image is too small to cover the whole form, it is repeated to tile the form.

The PictureBox object’s Image property also displays a persistent image. The control’s SizeMode property determines how Visual Basic uses the image to cover the control. This property can take the values Normal (the image is drawn at full scale in the upper-left corner of the PictureBox and is cropped if it is too big), StretchImage (the image is stretched or squashed to fit the control, possibly changing its shape), AutoSize (the PictureBox resizes to fit the image), and CenterImage (the image is drawn at full scale in the center of the PictureBox and is cropped if it is too big).

One relatively easy method for implementing AutoRedraw is to make a Bitmap and assign it to a PictureBox object’s Image property. Then the PictureBox automatically redisplays the image whenever it is exposed. The following example demonstrates this approach.

This program’s form contains a PictureBox named picCanvas with its Dock property set to Full, so it covers the entire form. When the form is loaded or resizes, its event handlers call the DrawDiamond subroutine.

DrawDiamond gets the PictureBox object’s size and makes a Bitmap that fits it. It makes a HatchBrush and uses it to fill the Bitmap. The code then defines the points needed to draw a diamond-shaped polygon on the form, fills the polygon with white, and outlines it in black.

The next statement is the key. It assigns the Bitmap to the PictureBox object’s Image property.

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _  Handles MyBase.Load     DrawDiamond() End Sub Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) _  Handles MyBase.Resize     DrawDiamond() End Sub Private Sub DrawDiamond()     ' Get the drawing surface's size.     Dim wid As Integer = picCanvas.ClientSize.Width     Dim hgt As Integer = picCanvas.ClientSize.Height     ' Do nothing if we have no size.     ' This happens, for example, if the form is minimized.     If wid < 1 Or hgt < 1 Then Exit Sub     ' Make a Bitmap and Graphics to fit.     Dim bm As New Bitmap(wid, hgt)     Using gr As Graphics = Graphics.FromImage(bm)         ' Fill the drawing area with a hatch pattern.         Using bg_brush As New HatchBrush(HatchStyle.HorizontalBrick, _           Color.Blue, Color.Aqua)             gr.FillRectangle(bg_brush, picCanvas.ClientRectangle)         End Using         ' Draw a dimond.         Dim pts() As Point = { _             New Point(wid \ 2, 0), _             New Point(wid, hgt \ 2), _             New Point(wid \ 2, hgt), _             New Point(0, hgt \ 2) _         }         gr.FillPolygon(Brushes.White, pts)         gr.DrawPolygon(Pens.Black, pts)         ' Display the result.         picCanvas.Image = bm     End Using ' gr End Sub 

Whenever this program is hidden and exposed, the picCanvas PictureBox automatically redisplays its image.

Some programs don’t need to redraw their images when the form resizes. For example, a mapping application might display its map at a specific size. In that case, you don’t need to redraw the map in the form’s Resize event handler. Instead, you would probably add menus and buttons to let the user zoom in and out, and scroll to different parts of the map. In an application such as that one, the code would need to draw images only when the content changed. The rest is automatic.

Other applications draw in several routines and not just in the form’s Load and Resize event handlers. For example, a drawing program might let the user draw various shapes (such as lines, rectangles, ellipses, and free-form curves). The program would need to add these shapes to a Bitmap as they were drawn and display the result.

In programs such as this, you can create Bitmap and Graphics objects at a module or application level and then use them whenever the user modifies the image.

The following code lets the user draw free-form curves. At the module level, it declares the variables m_Bitmap and m_Graphics, as well as some variables used while the user is drawing. When the form is loaded and when the user clicks the File menu’s Clear command, the program calls the MakeNewBitmap subroutine.

MakeNewBitmap creates a new Bitmap to fit the form’s picCanvas control and makes a Graphics object attached to it. It clears the Bitmap with the form’s background color and displays the result by setting the picCanvas control’s Image property to the Bitmap.

When the picCanvas control receives a MouseDown event, it records the mouse’s X and Y coordinates and sets m_Drawing to True to indicate that a scribble is in progress.

The picCanvas_MouseMove event handler checks m_Drawing and, if it is True, draws a line connecting the mouse’s previous position to its current location and saves the mouse’s new X and Y coordinates for the next time. It then sets the picCanvas control’s Image property to the Bitmap to display the new results.

Finally, the picCanvas_MouseUp event handler sets m_Drawing to False so that future MouseMove events don’t draw on the Bitmap.

  ' The Bitmap and Graphics objects we will draw on. Private m_Bitmap As Bitmap Private m_Graphics As Graphics ' Used for scribbling. Private m_Drawing As Boolean Private m_X As Integer Private m_Y As Integer ' Make the initial blank image. Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _  Handles MyBase.Load     MakeNewBitmap() End Sub ' Make a new blank image. Private Sub mnuFileClear_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles mnuFileClear.Click     MakeNewBitmap() End Sub ' Make a new Bitmap to fit the canvas. Private Sub MakeNewBitmap()     ' Get the drawing surface's size.     Dim wid As Integer = picCanvas.ClientSize.Width     Dim hgt As Integer = picCanvas.ClientSize.Height     ' Make a Bitmap and Graphics to fit.     m_Bitmap = New Bitmap(wid, hgt)     m_Graphics = Graphics.FromImage(m_Bitmap)     ' Clear the drawing area.     m_Graphics.Clear(Me.BackColor)     ' Display the result.     picCanvas.Image = m_Bitmap End Sub ' Start scribbling. Private Sub picCanvas_MouseDown(ByVal sender As Object, _  ByVal e As System.Windows.Forms.MouseEventArgs) Handles picCanvas.MouseDown     m_Drawing = True     m_X = e.X     m_Y = e.Y End Sub ' Continue scribbling. Private Sub picCanvas_MouseMove(ByVal sender As Object, _  ByVal e As System.Windows.Forms.MouseEventArgs) Handles picCanvas.MouseMove     If Not m_Drawing Then Exit Sub     m_Graphics.DrawLine(Pens.Black, m_X, m_Y, e.X, e.Y)     m_X = e.X     m_Y = e.Y     ' Display the result.     picCanvas.Image = m_Bitmap End Sub ' Stop scribbling. Private Sub picCanvas_MouseUp(ByVal sender As Object, _  ByVal e As System.Windows.Forms.MouseEventArgs) Handles picCanvas.MouseUp     m_Drawing = False End Sub 

Figure 23-1 shows this program in action.

image from book
Figure 23-1: Program Scribble automatically redisplays its image when the form is hidden and exposed.

A final issue related to auto-redraw is resizing. If the user makes the form larger or smaller, you need to figure out what to do about the auto-redraw image. There are several approaches you can take, depending on your application.

The simplest approach is to not allow the user to resize the form or at least not to resize the PictureBox that displays the auto-redraw image. Then you can ignore the whole issue.

A second approach is to create a new Bitmap of the new correct size. Use a Graphics object’s Clear method to erase the new Bitmap. Then use the object’s DrawImage method to copy the contents of the old Bitmap into the new one.

In this approach, if the new Bitmap is larger than the old one, all of its data is saved. On the other hand, if the new Bitmap is smaller, then some of the old drawing is lost. You can preserve that information if you only allow the Bitmap to grow and never shrink. When the user resizes the form, you make the new Bitmap object’s width and height the larger of the old Bitmap object’s size and the form’s new size.

Finally, if you think the program will often run maximized, you could just allocate a really big Bitmap when the program begins and forget the whole resizing issue.

Pixel-by-Pixel Operations

The Bitmap object provides two methods, GetPixel and SetPixel, that let a program easily read and write pixel values in the image. The following discussion describes an example that uses these methods to invert an image.

GetPixel and SetPixel are easy to use and fast enough for many applications. For high-performance graphics, however, they are relatively slow. The section “Unsafe Pixel Manipulation” later in this chapter explains how you can use unsafe methods to access pixel data more directly. This is a bit more difficult, but it is much faster for large images.

GetPixel and SetPixel

The Bitmap object’s GetPixel method returns a Color structure for a pixel in a specific X and Y location. SetPixel sets the Color of a pixel at a particular position. These two methods are quite easy to use and provide good enough performance for many applications.

The following code shows how a program can use those methods to invert the pixel values in an image.

When the user selects the File menu’s Open command and selects a file, the program loads the file into the Bitmap named bm. It copies the image into a new Bitmap named source_bm and disposes of the original Bitmap so that the image’s file isn’t locked. It then assigns source_bm to the picSource PictureBox object’s Image property to display the original image.

The program then arranges its controls nicely. The picSource control’s SizeMode property is set to AutoSize so that it automatically resizes itself to fit the picture. The program gives the picDest PictureBox the same size, positions it to the right of picSource, and resizes the form to fit the two PictureBox objects.

Next, the program copies the source Bitmap into a new Bitmap named dest_bm and calls subroutine InvertImage to invert the pixels in that bitmap. When InvertImage returns, the program assigns the dest_bm Bitmap to the picDest control’s Image property to display the result.

Subroutine InvertImage loops over all of the pixels in the image. It uses the bitmap’s GetPixel function to get the color of each pixel. It inverts the red, green, and blue components of the pixel’s color by subtracting them from the maximum allowed value 255. It then calls the destination Bitmap’s SetPixel method to set the result pixel’s value.

  Private Sub mnuFileOpen_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles mnuFileOpen.Click     If dlgOpenImage.ShowDialog() = DialogResult.OK Then         ' Load and display the image.         Dim bm As New Bitmap(dlgOpenImage.FileName)         Dim source_bm As New Bitmap(bm)         bm.Dispose()         picSource.Image = source_bm         ' Arrange the controls.         picDest.Size = picSource.Size         ' Make the result Bitmap.         Dim dest_bm As New Bitmap(source_bm)         ' Invert the image's pixels.         InvertImage(dest_bm)         ' Display the results.         picDest.Image = dest_bm     End If End Sub Private Sub InvertImage(ByVal bm As Bitmap)     ' Process the image's pixels.     For y As Integer = 0 To bm.Height - 1         For x As Integer = 0 To bm.Width - 1             ' Get this pixel's color.             Dim clr As Color = bm.GetPixel(x, y)             ' Invert the color's components.             clr = Color.FromArgb(255, _                 255 - clr.R, _                 255 - clr.G, _                 255 - clr.B)             ' Set the result pixel's color.             bm.SetPixel(x, y, clr)         Next x     Next y End Sub 

Figure 23-2 shows the result. The output image on the right is essentially the photographic negative of the original image on the left.

image from book
Figure 23-2: This program uses GetPixel and SetPixel to invert an image’s pixel values.

Unsafe Pixel Manipulation

The GetPixel and SetPixel methods are very easy to use, and they are fast enough for many applications. For example, a program that generates fractals such as the Mandelbrot set spends a considerable amount of time calculating colors for each individual pixel. If it takes the program 5 seconds to generate the image and a tenth of a second of that time is spent by the SetPixel method, then SetPixel is probably fast enough. Using unsafe array methods may shave a few hundredths of a second off the total time, but the program’s time is dominated by the code that calculates the pixels’ colors, so it’s hardly worth the extra complication.

However, suppose that you need to transform a series of images very quickly to display an animated sequence. In that case, the time spent by GetPixel and SetPixel may be significant. In that case, you may get much better performance using unsafe methods.

The basic idea is to directly access the array of bytes containing the red, green, and blue component values for the image’s pixels. The Bitmap object’s LockBits method copies the pixel data for a rectangular part of the image into a temporary buffer where you can manipulate it. Later, you call the UnlockBits method to copy any changes you made back into the bitmap.

Unfortunately the LockBits method returns the buffer of data as a pointer to memory and Visual Basic cannot work directly with that kind of pointer. To resolve this problem, you can use the Marshal class’s Copy method to move the data into a Visual Basic array. You can then modify the data and, when you are finished, use Marshal.Copy to move the results back into the buffer.

The following code shows the BitmapBytesRGB24 class that makes this somewhat simpler for the main program. This class works with 24-bit image representations. Your call to LockBits can specify other formats, but this one is particularly easy to work with because it uses one byte for each of the pixels’ red, green, and blue components.

The class’s ImageBytes array will contain the pixel data stored as a one-dimensional array. Each pixel is represented by a byte for its blue component, a byte for its green component, and a byte for its red component, in that order.

The RowSizeBytes property tells how many bytes are stored in the array per row of pixels. The system may pad the array, so the number of bytes in each row is a multiple of four or some other number that is convenient for the operating system. Thus, RowSizeBytes may not always be three times the number of pixels in each row.

The constant PixelDataSize is 24 for this class because it works with 24-bit (3-byte) pixel data.

The class’s constructor takes as a parameter a reference to a Bitmap and saves that reference for later use.

The class next declares a BitmapData object named m_BitmapData. This object will contain data describing the bitmap.

The LockBitmap method creates a Rectangle bounding the bitmap. This is the area in the bitmap that the routine will lock. This class doesn’t mess around and simply locks the entire bitmap.

LockBitmap calls the Bitmap object’s LockBits method, passing it the bounding Rectangle, a flag indicating that it wants to lock the data for reading and writing, and a flag indicating that we want to work with 24-bit pixel data. LockBits returns information about the bitmap in a BitmapData object, which the routine saves in m_BitmapData. The routine sets the RowSizeBytes value so that it is easy for the main program to use.

LockBitmap then calculates the total number of bytes needed to hold the pixel data, makes the ImageBytes array big enough, and calls Marshal.Copy to copy the pixel data into the array.

The class’s UnlockBitmap method copies the modified pixel data back into the bitmap. It recalculates the size of the array and uses Marshal.Copy to copy the data from the ImageBytes array back into the buffer allocated by LockBits. Finally, it calls the Bitmap object’s UnlockBits method.

  Imports System.Drawing.Imaging Imports System.Runtime.InteropServices Public Class BitmapBytesRGB24     ' Provide public access to the picture's     Public ImageBytes() As Byte     Public RowSizeBytes As Integer     Public Const PixelDataSize As Integer = 24     ' A reference to the Bitmap.     Private m_Bitmap As Bitmap     ' Save a reference to the bitmap.     Public Sub New(ByVal bm As Bitmap)         m_Bitmap = bm     End Sub     ' Bitmap data.     Private m_BitmapData As BitmapData     ' Lock the bitmap's data.     Public Sub LockBitmap()         ' Lock the bitmap data.         Dim bounds As Rectangle = New Rectangle( _             0, 0, m_Bitmap.Width, m_Bitmap.Height)         m_BitmapData = m_Bitmap.LockBits(bounds, _             Imaging.ImageLockMode.ReadWrite, _             Imaging.PixelFormat.Format24bppRgb)         RowSizeBytes = m_BitmapData.Stride         ' Allocate room for the data.         Dim total_size As Integer = m_BitmapData.Stride * m_BitmapData.Height         ReDim ImageBytes(total_size)         ' Copy the data into the ImageBytes array.         Marshal.Copy(m_BitmapData.Scan0, ImageBytes, _             0, total_size)     End Sub     ' Copy the data back into the Bitmap     ' and release resources.     Public Sub UnlockBitmap()         ' Copy the data back into the bitmap.         Dim total_size As Integer = m_BitmapData.Stride * m_BitmapData.Height         Marshal.Copy(ImageBytes, 0, _             m_BitmapData.Scan0, total_size)         ' Unlock the bitmap.         m_Bitmap.UnlockBits(m_BitmapData)         ' Release resources.         ImageBytes = Nothing         m_BitmapData = Nothing     End Sub End Class 

The following code shows how a main program can use the BitmapBytesRGB24 class to invert an image’s pixels. The code creates a new BitmapBytesRGB24 object, passing the constructor the Bitmap that it wants to modify. It then calls the object’s LockBitmap method to copy the pixel data into the object’s ImageBytes array. Next, the program loops over the rows in the image. For each row, the code calculates the position in the pixel data that holds the row’s first pixel’s information. It then loops over the pixels in the row, modifying each pixel’s blue, green, and red components. Remember that the components are in stored in the order blue, green, red. When it has finished modifying the pixel data, the program calls the BitmapBytesRGB24 object’s UnlockBitmap method to copy the results back into the bitmap.

  ' Invert the pixel values in this Bitmap.  Private Sub InvertImage(ByVal bm As Bitmap)     ' Make a BitmapBytesRGB24 object.     Dim bm_bytes As New BitmapBytesRGB24(bm)     ' Lock the bitmap.     bm_bytes.LockBitmap()     Dim pix As Integer     For y As Integer = 0 To bm.Height - 1         pix = y * bm_bytes.RowSizeBytes         For x As Integer = 0 To bm.Width - 1             ' Blue component.             bm_bytes.ImageBytes(pix) = CByte(255) - bm_bytes.ImageBytes(pix)             pix += 1             ' Green component.             bm_bytes.ImageBytes(pix) = CByte(255) - bm_bytes.ImageBytes(pix)             pix += 1             ' Red component.             bm_bytes.ImageBytes(pix) = CByte(255) - bm_bytes.ImageBytes(pix)             pix += 1         Next x     Next y     ' Unlock the bitmap.     bm_bytes.UnlockBitmap() End Sub 

This is quite a bit more complicated than the previous program that uses GetPixel and SetPixel, so it’s not the best method for simple applications. For high-performance image processing, however, the extra complication is sometimes worth it. In one set of tests on a 798-MHz Athlon 64 processor, the previous version using GetPixel and SetPixel took roughly 1.109 seconds to invert an 800 × 600 pixel image, while the version using the BitmapBytesRGB24 class took only 0.047 seconds.




Visual Basic 2005 with  .NET 3.0 Programmer's Reference
Visual Basic 2005 with .NET 3.0 Programmer's Reference
ISBN: 470137053
EAN: N/A
Year: 2007
Pages: 417

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net