|
-
Jan 18th, 2006, 09:23 AM
#1
Thread Starter
PowerPoster
LockBits
VB Code:
Public Function Mask(ByVal iPic As Bitmap) As Bitmap
Dim NewMask As Bitmap = New Bitmap(iPic.Width, iPic.Height)
Dim GDColor As Color
Dim i As New Rectangle
i.Width = iPic.Width
i.Height = iPic.Height
Dim BitData As BitmapData = NewMask.LockBits(i, Imaging.ImageLockMode.ReadWrite, iPic.PixelFormat)
Dim bit2data As BitmapData = iPic.LockBits(i, ImageLockMode.ReadWrite, iPic.PixelFormat)
For y As Integer = 0 To iPic.Height - 1
For x As Integer = 0 To iPic.Width - 1
GDColor = iPic.GetPixel(x, y) ' ERROR HERE
If GDColor.ToArgb <> Color.Black.ToArgb Then
NewMask.SetPixel(x, y, Color.Black)
Else
NewMask.SetPixel(x, y, Color.White)
End If
Next x
Next y
NewMask.UnlockBits(BitData)
iPic.UnlockBits(bit2data)
Return NewMask
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 :/
-
Jan 18th, 2006, 09:39 AM
#2
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
-
Jan 18th, 2006, 09:50 AM
#3
Hyperactive Member
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
-
Jan 18th, 2006, 09:52 AM
#4
Thread Starter
PowerPoster
Re: LockBits
Arr I understand now, brilliant thnaks guys.
Pino
-
Jan 18th, 2006, 10:18 AM
#5
Hyperactive Member
Re: LockBits
You should avoid color.fromargb and color.toargb too as they are slow.
I did the function like this:
VB Code:
Public Function mask2(ByVal iPic As Bitmap) As Bitmap
' assuming 32 bits per pixel color!!!
Dim NewMask As New Bitmap(iPic.Width, iPic.Height)
Dim i As New Rectangle
i.Width = iPic.Width
i.Height = iPic.Height
Dim sourceData As BitmapData = iPic.LockBits(i, Imaging.ImageLockMode.ReadWrite, iPic.PixelFormat)
Dim NewData As BitmapData = NewMask.LockBits(i, ImageLockMode.ReadWrite, iPic.PixelFormat)
' arrays to store the colors
Dim pixels(i.Width * i.Height - 1) As Integer
Dim pixels2(i.Width * i.Height - 1) As Integer
' copy the data
Marshal.Copy(sourceData.Scan0, pixels, 0, pixels.Length)
Dim index As Integer ' location of pixel(x,y) in pixels array
For y As Integer = 0 To iPic.Height - 1
For x As Integer = 0 To iPic.Width - 1
index = (y * i.Width) + x ' pixels above current row + pixels in current row up to x
If pixels(index) = &HFF000000 Then 'black
pixels2(index) = &HFFFFFFFF ' white
Else
pixels2(index) = &HFF000000 ' black
End If
Next
Next
' Copy data into bitmapdata
Marshal.Copy(pixels2, 0, NewData.Scan0, pixels2.Length)
'unlock
iPic.UnlockBits(sourceData)
NewMask.UnlockBits(NewData)
Return NewMask
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:
alpha = (pixels(i) >> 24) And &HFF
red = (pixels(i) >> 16) And &HFF
green = (pixels(i) >> 8) And &HFF
blue = pixels(i) And &HFF
then you will want to write a color back:
VB Code:
pixels(i) = (255 << 24) _
Or (grey << 16) _
Or (grey << 8) _
Or grey
-
Jan 18th, 2006, 10:56 AM
#6
Thread Starter
PowerPoster
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
-
Jan 18th, 2006, 11:01 AM
#7
Hyperactive Member
Re: LockBits
I had imports system.runtime.interopservices
and imports system.drawing.imaging
system.runtime.interopservices.marshal
-
Jan 18th, 2006, 11:19 AM
#8
Thread Starter
PowerPoster
Re: LockBits
Arr I was missing the runtime improts.
Thanks for speedy replys!
-
Jan 18th, 2006, 03:32 PM
#9
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.
-
Jan 18th, 2006, 04:46 PM
#10
Thread Starter
PowerPoster
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
-
Jan 19th, 2006, 07:19 AM
#11
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.
-
Jan 19th, 2006, 11:46 AM
#12
Thread Starter
PowerPoster
Re: LockBits
Yes sir, Its done. I will strive to achieve speed.
-
Oct 24th, 2011, 03:26 PM
#13
New Member
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.
-
Oct 24th, 2011, 03:41 PM
#14
New Member
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?
-
Oct 24th, 2011, 05:41 PM
#15
Re: LockBits
The simplest way is to convert almost any bitmap or image to the 32 bit ARGB format is:
Code:
Dim bmp32 As New Bitmap(bmp24)
BB
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|