Results 1 to 15 of 15

Thread: LockBits

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Dec 2003
    Posts
    4,787

    LockBits

    VB Code:
    1. Public Function Mask(ByVal iPic As Bitmap) As Bitmap
    2.  
    3.         Dim NewMask As Bitmap = New Bitmap(iPic.Width, iPic.Height)
    4.         Dim GDColor As Color
    5.  
    6.         Dim i As New Rectangle
    7.         i.Width = iPic.Width
    8.         i.Height = iPic.Height
    9.  
    10.         Dim BitData As BitmapData = NewMask.LockBits(i, Imaging.ImageLockMode.ReadWrite, iPic.PixelFormat)
    11.         Dim bit2data As BitmapData = iPic.LockBits(i, ImageLockMode.ReadWrite, iPic.PixelFormat)
    12.  
    13.         For y As Integer = 0 To iPic.Height - 1
    14.             For x As Integer = 0 To iPic.Width - 1
    15.                 GDColor = iPic.GetPixel(x, y) ' ERROR HERE
    16.  
    17.                 If GDColor.ToArgb <> Color.Black.ToArgb Then
    18.                     NewMask.SetPixel(x, y, Color.Black)
    19.                 Else
    20.                     NewMask.SetPixel(x, y, Color.White)
    21.                 End If
    22.             Next x
    23.         Next y
    24.  
    25.         NewMask.UnlockBits(BitData)
    26.         iPic.UnlockBits(bit2data)
    27.  
    28.         Return NewMask
    29.     End Function

    Am i using lockbits incorrectly? I've done my research it seems ok, but it says that my bitmap is locked on the line above. I have it set to read/write though :/

  2. #2
    Frenzied Member Phill64's Avatar
    Join Date
    Jul 2005
    Location
    Queensland, Australia
    Posts
    1,201

    Re: LockBits

    the idea is, you either use the get/set pixel method.. or you lock the bitmap object, and directly modify the bytes of that bitmap, where you will set 3 bytes for each of your pixels, the r g and b

    i'm not sure this is possible in vb, i know it is in c# and if you search for lockbits by wossname you'll find plenty of posts about it

  3. #3
    Hyperactive Member
    Join Date
    Jul 2005
    Posts
    297

    Re: LockBits

    Getpixel won't work on a locked bitmap as it is locked.

    What you do is:

    Lockbits.
    Define an array to hold the int32 colors.
    Marshal.Copy the locked bitmapData into the array.
    Alter the colors in the array.
    Marshal.copy the array back into the bitmapData.
    Unlock bits.

    There are lots of places for error though.

    When it is working it should be just a bit slower than using c#, lockbits and unsafe code (pointers).

    see the inverse filter here
    http://www.pscode.com/vb/scripts/Sho...4058&lngWId=10

    http://www.bobpowell.net/lockingbits.htm
    (bobs loops with readbyte are considerably slow than using arrays and marshal.copy)

    explanations and drawings here:
    http://www.codersource.net/csharp_image_Processing.aspx

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Dec 2003
    Posts
    4,787

    Re: LockBits

    Arr I understand now, brilliant thnaks guys.

    Pino

  5. #5
    Hyperactive Member
    Join Date
    Jul 2005
    Posts
    297

    Re: LockBits

    You should avoid color.fromargb and color.toargb too as they are slow.
    I did the function like this:

    VB Code:
    1. Public Function mask2(ByVal iPic As Bitmap) As Bitmap
    2.  
    3.         ' assuming 32 bits per pixel color!!!
    4.  
    5.         Dim NewMask As New Bitmap(iPic.Width, iPic.Height)
    6.         Dim i As New Rectangle
    7.         i.Width = iPic.Width
    8.         i.Height = iPic.Height
    9.  
    10.         Dim sourceData As BitmapData = iPic.LockBits(i, Imaging.ImageLockMode.ReadWrite, iPic.PixelFormat)
    11.         Dim NewData As BitmapData = NewMask.LockBits(i, ImageLockMode.ReadWrite, iPic.PixelFormat)
    12.  
    13.         ' arrays to store the colors
    14.         Dim pixels(i.Width * i.Height - 1) As Integer
    15.         Dim pixels2(i.Width * i.Height - 1) As Integer
    16.  
    17.         ' copy the data
    18.         Marshal.Copy(sourceData.Scan0, pixels, 0, pixels.Length)
    19.  
    20.         Dim index As Integer ' location of pixel(x,y) in pixels array
    21.  
    22.         For y As Integer = 0 To iPic.Height - 1
    23.             For x As Integer = 0 To iPic.Width - 1
    24.                 index = (y * i.Width) + x ' pixels above current row + pixels in current row up to x
    25.                 If pixels(index) = &HFF000000 Then 'black
    26.                     pixels2(index) = &HFFFFFFFF ' white
    27.                 Else
    28.                     pixels2(index) = &HFF000000 ' black
    29.                 End If
    30.             Next
    31.         Next
    32.  
    33.         ' Copy data into bitmapdata
    34.         Marshal.Copy(pixels2, 0, NewData.Scan0, pixels2.Length)
    35.         'unlock
    36.         iPic.UnlockBits(sourceData)
    37.         NewMask.UnlockBits(NewData)
    38.  
    39.         Return NewMask
    40.     End Function

    If I change the black from &HFF000000 to color.black.toargb and the white similarly, and time it, then it slows down a bit (~4ms instead of ~2ms for a 100,100 bitmap)

    When you need the A, R, G, B values then you need to avoid color.toargb. You can do this by using a byte array instead of an int32 array. Or you can use this to split the values from an int:
    VB Code:
    1. alpha = (pixels(i) >> 24) And &HFF
    2.             red = (pixels(i) >> 16) And &HFF
    3.             green = (pixels(i) >> 8) And &HFF
    4.             blue = pixels(i) And &HFF

    then you will want to write a color back:
    VB Code:
    1. pixels(i) = (255 << 24) _
    2.             Or (grey << 16) _
    3.             Or (grey << 8) _
    4.             Or grey

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Dec 2003
    Posts
    4,787

    Re: LockBits

    This is impresive stuff, I was tolf that toargb was faster but I think you may be correct. I appriciate you writing this function,

    What is marshal?

    thanks

  7. #7
    Hyperactive Member
    Join Date
    Jul 2005
    Posts
    297

    Re: LockBits

    I had imports system.runtime.interopservices
    and imports system.drawing.imaging
    system.runtime.interopservices.marshal

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Dec 2003
    Posts
    4,787

    Re: LockBits

    Arr I was missing the runtime improts.

    Thanks for speedy replys!

  9. #9
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    Re: LockBits

    The thing to remember her is thta you are not dealing with colors any more, you are dealing in integers (32bit images).

    Sadly VB.net insists on cecking array bounds within th piixel data and this is why its slower, also there is a bit og a delay with boxing/unnboxing with marshal.copy().

    Unsafe code vircumvents both of these for much improved performance.
    I don't live here any more.

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Dec 2003
    Posts
    4,787

    Re: LockBits

    The performance differance between lockbits and non lockbits tho is clearly noticable and so far looks more than adaquete, have to wait and see final tests though

    Pino

  11. #11
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    Re: LockBits

    I don't ever want to see you use the word adequate ever again Strike it from thine vocabulary.

    Adequate never is.

    I don't live here any more.

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Dec 2003
    Posts
    4,787

    Re: LockBits

    Yes sir, Its done. I will strive to achieve speed.


  13. #13
    New Member
    Join Date
    Oct 2011
    Posts
    2

    Re: LockBits

    When using the above example with the correct imports etc I seem to get:

    "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

    on the line:

    Code:
    ' copy the data
            Marshal.Copy(sourceData.Scan0, pixels, 0, pixels.Length)
    I've tried googling it but to no success, any ideas what may be causing it? Thanks.

  14. #14
    New Member
    Join Date
    Oct 2011
    Posts
    2

    Re: LockBits

    Found the issue, was with the wrong pixel format image being used. If you are importing an image from file and it could be any extension/pixel format is there a way to convert it to a standard 32bits per pixel format?

  15. #15

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