none
Bitmap.LockBits issue

    Question

  • hi,

      I am a little confused about Bitmap.LockBits.

     I create PixelFormat.Format32bppRgb bitmap, but it can successfully be locked with  PixelFormat.Format24bppRgb, without exception raised.

    can anyone tell me why? Does lockbits allocate another memory in system and intelligently copy the image data to the memory respect to PixelFormat you specified?

     

    Thanks

    Wellon

    Wednesday, October 27, 2010 5:07 PM

All replies

  • You supply the PixelFormat.  LockBits doesn't care which you specify.  If you try to copy too many bytes, you'll get an error.
    Wednesday, October 27, 2010 5:34 PM
  •  "LockBits doesn't care which you specify"

      Is that true?

    if I iterate each pixel after lock, what steps should i take, 4byte or 3byte to next pixel?

    since this a 32bit bitmap, i would think i should step 4byte to next pixel.

    But I notice some .net framework sample(Parallel\morph\fastbitmap.cs) lock the 32bit bitmap with 24bit, and step 3byte to next pixel,  that works fine, do you know why?

     

    The following is the .net framework source code, i can't see more, because it goes to navtive code.

     

    [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        public BitmapData LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)
        {
    
          GPRECT gprect = new GPRECT(rect);
          int status = SafeNativeMethods.Gdip.GdipBitmapLockBits(new HandleRef(this, nativeImage), ref gprect,
                              flags, format, bitmapData);
     
          if (status != SafeNativeMethods.Gdip.Ok)
            throw SafeNativeMethods.Gdip.StatusException(status);
    
          return bitmapData;
        }

     

    thanks

    Wellon

    Thursday, October 28, 2010 3:46 AM
  • I don't know if this helps, but there's MSDN documentation for the C++ method LockBits (part of the C++ Bitmap class that wraps that part of the GDI+ 'flat' API).

    The Bitmap::LockBits method wraps the GdipBitmapLockBits GDI+ API method (used in the code you show above).

    Link is:

    http://msdn.microsoft.com/en-us/library/ms536298%28v=VS.85%29.aspx

    It states that the specified portion of the bitmap is locked and a temporary buffer is returned (accessed through the BitmapData class). The pixel format of this buffer doesn't need to be the same as that of the original image, as long as the two are inter-convertible. The buffer is committed back to the image data when UnlockBits is called.

    I guess this explains why you can do what you can do.

    However, the MSDN documentation for the .NET method (Bitmap . LockBits) - or at least my understanding of it - does not specifically state that this is allowed.

    Thursday, October 28, 2010 7:45 PM
  • Hi:

    The short answer is, just use the same pixel format for both the image and the lock.  There is no reason not to.

     

    The longer answer is, its just memory, and if you tell LockBits to lock 32bpp bits as 24bpp, it will give you the same pointer to the beginning of the data.  It will convert in trivial cases.  Again though, I see no reason to do it this way, and you can lose meaningful information (like alpha) if it was in the 4th byte.

    Wendell

    Friday, October 29, 2010 9:33 PM
  • Thanks, Chirs50. That can explain my confusion.
    Tuesday, November 02, 2010 3:30 AM