VB has pros and cons. This is a definite con.
All new articles provide code in C# and VB.NET.
James Maeding wrote:
> I generally work with large scans, so speed matters for me.
> I wanted to set transparency for colors whose RGB byte total is less than 10 (light colors).
> I tried the Bob powell method listed at:
>
http://www.bobpowell.net/lockingbits.htm >
> which locks a source and dest bitmap, then writes to the dest bitmap with:
> Marshal.WriteByte(bmd.Scan0, offset, currentByte)
>
> This is proving to be way too slow for images, say 2000x2000 pixels.
>
> I think I have figured out a solution, based on looking at lots of others' code, I am interested in any comments on if I
> am right or wrong...
> Here is the solution summary:
> 1) lock source image and write bytes to byte array
> 2) make dest bitmap and lock
> 3) modify byte array as desired
> 4) write byte array to dest image memory all at once and unlock dest image
>
> It seems a byte array is way faster to edit, and worth the trouble to write back at the end.
> I have only done this for black and white conversions but I think the pattern applies to all bitmap manipulations.
>
> Detailed code that changes image to black and white very fast (not transparency involved here):
> 1) lock the source bitmap,
> marshall.copy the bytes to a byte array
> unlock the source.
> <code>
> ' Lock source bitmap in memory
> Dim sourceData As BitmapData = source.LockBits(New Rectangle(0, 0, source.Width, source.Height),
> ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
>
> ' Copy image data to binary array
> Dim imageSize As Integer = sourceData.Stride * sourceData.Height
> Dim sourceBuffer As Byte() = New Byte(imageSize - 1) {}
> Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize)
>
> ' Unlock source bitmap
> source.UnlockBits(sourceData)
> <code>
>
> 2) Make destination bitmap,
> lock bits
> make desination buffer (leave bitmap locked for later write)
> <code>
> ' Create destination bitmap
> Dim destination As Bitmap = New Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed)
>
> ' Lock destination bitmap in memory
> Dim destinationData As BitmapData = destination.LockBits(New Rectangle(0, 0, destination.Width,
> destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed)
>
> ' Create destination buffer
> imageSize = destinationData.Stride * destinationData.Height
> Dim destinationBuffer As Byte() = New Byte(imageSize - 1) {}
> <code>
>
> 3) modify dest buffer as needed, this code loops through source and changes destination pixels to black or white:
> <code>
> Dim sourceIndex As Integer = 0
> Dim destinationIndex As Integer = 0
> Dim pixelTotal As Integer = 0
> Dim destinationValue As Byte = 0
> Dim pixelValue As Integer = 128
> Dim height As Integer = source.Height
> Dim width As Integer = source.Width
> Dim threshold As Integer = 650
>
> ' Iterate lines
> Dim y As Integer = 0
> Do While y < height
> sourceIndex = y * sourceData.Stride
> destinationIndex = y * destinationData.Stride
> destinationValue = 0
> pixelValue = 128
>
> ' Iterate pixels
> Dim x As Integer = 0
> Do While x < width
> ' Compute pixel brightness (i.e. total of Red, Green, and Blue values)
> pixelTotal = CInt(sourceBuffer(sourceIndex + 1)) + CInt(sourceBuffer(sourceIndex + 2)) +
> CInt(sourceBuffer(sourceIndex + 3))
> If pixelTotal > threshold Then
> destinationValue += CByte(pixelValue)
> End If
> If pixelValue = 1 Then
> destinationBuffer(destinationIndex) = destinationValue
> destinationIndex += 1
> destinationValue = 0
> pixelValue = 128
> Else
> pixelValue >>= 1
> End If
> sourceIndex += 4
> x += 1
> Loop
> If pixelValue <> 128 Then
> destinationBuffer(destinationIndex) = destinationValue
> End If
> y += 1
> Loop
> <code>
>
> 4) write buffer to destination bits all at once
> unlock dest bitmap
> <code>
> ' Copy binary image data to destination bitmap
> Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize)
>
> ' Unlock destination bitmap
> destination.UnlockBits(destinationData)
> <code>
>
> Then do whatever with the bitmap, save to file, write to form, whatever.
> This runs like 50 times faster than writing to the destination bitmap's pixels one by one.
> Am I off here? I have only been doing GDI+ for a couple weeks...