Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
.NET Framework 3.5
Bitmap Class
Bitmap Methods
LockBits Method
 LockBits Method (Rectangle, ImageLo...
Collapse All/Expand All Collapse All
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
.NET Framework Class Library
Bitmap..::.LockBits Method (Rectangle, ImageLockMode, PixelFormat)

Locks a Bitmap into system memory.

Namespace:  System.Drawing
Assembly:  System.Drawing (in System.Drawing.dll)
Visual Basic (Declaration)
Public Function LockBits ( _
    rect As Rectangle, _
    flags As ImageLockMode, _
    format As PixelFormat _
) As BitmapData
Visual Basic (Usage)
Dim instance As Bitmap
Dim rect As Rectangle
Dim flags As ImageLockMode
Dim format As PixelFormat
Dim returnValue As BitmapData

returnValue = instance.LockBits(rect, _
    flags, format)
C#
public BitmapData LockBits(
    Rectangle rect,
    ImageLockMode flags,
    PixelFormat format
)
Visual C++
public:
BitmapData^ LockBits(
    Rectangle rect, 
    ImageLockMode flags, 
    PixelFormat format
)
JScript
public function LockBits(
    rect : Rectangle, 
    flags : ImageLockMode, 
    format : PixelFormat
) : BitmapData

Parameters

rect
Type: System.Drawing..::.Rectangle
A Rectangle structure specifying the portion of the Bitmap to lock.
flags
Type: System.Drawing.Imaging..::.ImageLockMode
An ImageLockMode enumeration specifying the access level (read/write) for the Bitmap.
format
Type: System.Drawing.Imaging..::.PixelFormat
A PixelFormat enumeration specifying the data format of this Bitmap.

Return Value

Type: System.Drawing.Imaging..::.BitmapData
A BitmapData containing information about this lock operation.
ExceptionCondition
ArgumentException

The PixelFormat is not a specific bits-per-pixel value.

-or-

The incorrect PixelFormat is passed in for a bitmap.

Exception

The operation failed.

The BitmapData specifies the attributes of the Bitmap, such as size, pixel format, the starting address of the pixel data in memory, and length of each scan line (stride).

When calling this method, you should use a member of the System.Drawing.Imaging..::.PixelFormat enumeration that contains a specific bits-per-pixel (BPP) value. Using System.Drawing.Imaging..::.PixelFormat values such as Indexed and Gdi will throw an.System..::.ArgumentException. Also, passing the incorrect pixel format for a bitmap will throw an System..::.ArgumentException.

The following code example demonstrates how to use the PixelFormat, Height, Width, and Scan0 properties; the LockBits and UnlockBits methods; and the ImageLockMode enumeration. This example is designed to be used with Windows Forms. To run this example, paste it into a form and handle the form's Paint event by calling the LockUnlockBitsExample method, passing e as PaintEventArgs.

Visual Basic
Private Sub LockUnlockBitsExample(ByVal e As PaintEventArgs)

    ' Create a new bitmap.
    Dim bmp As New Bitmap("c:\fakePhoto.jpg")

    ' Lock the bitmap's bits.  
    Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
    Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(rect, _
        Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)

    ' Get the address of the first line.
    Dim ptr As IntPtr = bmpData.Scan0

    ' Declare an array to hold the bytes of the bitmap.
    ' This code is specific to a bitmap with 24 bits per pixels.
    Dim bytes As Integer = bmpData.Stride * bmp.Height
    Dim rgbValues(bytes - 1) As Byte

    ' Copy the RGB values into the array.
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)

    ' Set every third value to 255. A 24bpp image will look red.
    For counter As Integer = 2 To rgbValues.Length - 1 Step 3
        rgbValues(counter) = 255
    Next

    ' Copy the RGB values back to the bitmap
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)

    ' Unlock the bits.
    bmp.UnlockBits(bmpData)

    ' Draw the modified image.
    e.Graphics.DrawImage(bmp, 0, 150)

End Sub
C#
    private void LockUnlockBitsExample(PaintEventArgs e)
        {

            // Create a new bitmap.
            Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");

            // Lock the bitmap's bits.  
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                bmp.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int bytes  = bmpData.Stride * bmp.Height;
���         byte[] rgbValues = new byte[bytes];

            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

            // Set every third value to 255. A 24bpp bitmap will look red.  
            for (int counter = 2; counter < rgbValues.Length; counter += 3)
                rgbValues[counter] = 255;

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

            // Unlock the bits.
            bmp.UnlockBits(bmpData);

            // Draw the modified image.
            e.Graphics.DrawImage(bmp, 0, 150);

        }

Visual C++
void LockUnlockBitsExample( PaintEventArgs^ e )
{
   // Create a new bitmap.
   Bitmap^ bmp = gcnew Bitmap( "c:\\fakePhoto.jpg" );

   // Lock the bitmap's bits.  
   Rectangle rect = Rectangle(0,0,bmp->Width,bmp->Height);
   System::Drawing::Imaging::BitmapData^ bmpData = bmp->LockBits( rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmp->PixelFormat );

   // Get the address of the first line.
   IntPtr ptr = bmpData->Scan0;

   // Declare an array to hold the bytes of the bitmap.
   // This code is specific to a bitmap with 24 bits per pixels.
   int bytes = bmpData->Stride * bmp->Height;
   array<Byte>^rgbValues = gcnew array<Byte>(bytes);

   // Copy the RGB values into the array.
   System::Runtime::InteropServices::Marshal::Copy( ptr, rgbValues, 0, bytes );

   // Set every third value to 255.  
   for ( int counter = 2; counter < rgbValues->Length; counter += 3 )
      rgbValues[ counter ] = 255;

   // Copy the RGB values back to the bitmap
   System::Runtime::InteropServices::Marshal::Copy( rgbValues, 0, ptr, bytes );

   // Unlock the bits.
   bmp->UnlockBits( bmpData );

   // Draw the modified image.
   e->Graphics->DrawImage( bmp, 0, 150 );
}

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 3.5, 2.0
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Example is wrong      ag1206d   |   Edit   |   Show History
Well, for some images it will work, whereas for others the result will be quite unexpected.
It will work only when there are no extra bytes on a scanline. The extra bytes are there to align the scanline length to 4-byte boudary.

Example      Dmitri Nesteruk   |   Edit   |   Show History

As ag1206d said, the example is completely wrong because the bitmap's stride can be greater than its width, and also because - guess what - it can be negative! So if you wanted to copy the bytes elsewhere, you would need to have two for loops which compute the exact address and place it into a preallocated memory lcoation.

I'm not sure what the above two are on about...      The MAZZTer   |   Edit   |   Show History
...but the Stride is the number of bytes that are being used to store one row of pixel data. The example is only wrong in that setting every third value to 255 will not produce a meaningful result since the Stride may include padding bytes as described.

The example technically works in that it shows how to use LockBits to manipulate bitmaps directly, but it's "wrong" in that the example code itself isn't terribly useful.

It should also be noted that every PixelFormat has a different pixel data format so this example is also a bit misleading... you should explicitly pass a specific PixelFormat value to LockBits, (or at least check the bitmap's PixelFormat) otherwise you could end up reading/writing in the wrong format if you LockBits on a bitmap that isn't in the format you expect or suppot. Passing a specific value causes an exception if you accidentally try to operate on a bitmap in this case.
Marshaling vs Direct Manipulation of the Bitmap Data      xMartian   |   Edit   |   Show History
Why not directly manipulate the bitmap data, as demonstrated in the following C++ code:

Byte* p = (Byte*)(void*)ptr;
for (counter i = 2, p+=2; counter<bytes; counter+=3, p+=3)
*p = 255;

Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Site Feedback
Page view tracker