Il existe un autre moyen, beaucoup plus rapide et pratique. Si vous regardez les constructeurs de Bitmap, vous en trouverez un qui prend un IntPtr comme dernier paramètre. Cette IntPtr sert à contenir les données des pixels. Comment l'utiliser ?
Dim imageWidth As Integer = 1920
Dim imageHeight As Integer = 1080
Dim fmt As PixelFormat = PixelFormat.Format32bppRgb
Dim pixelFormatSize As Integer = Image.GetPixelFormatSize(fmt)
Dim stride As Integer = imageWidth * pixelFormatSize
Dim padding = 32 - (stride Mod 32)
If padding < 32 Then stride += padding
Dim pixels((stride \ 32) * imageHeight) As Integer
Dim handle As GCHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned)
Dim addr As IntPtr = Marshal.UnsafeAddrOfPinnedArrayElement(pixels, 0)
Dim bitmap As New Bitmap(imageWidth, imageHeight, stride \ 8, fmt, addr)
Ce que vous avez maintenant, c'est un simple tableau d'entiers et une image bitmap référençant la même mémoire. Toute modification apportée au tableau d'entiers affectera directement le bitmap. Essayons ceci avec une simple transformation de la luminosité.
Public Sub Brightness(ByRef pixels() As Integer, ByVal scale As Single)
Dim r, g, b As Integer
Dim mult As Integer = CInt(1024.0f * scale)
Dim pixel As Integer
For i As Integer = 0 To pixels.Length - 1
pixel = pixels(i)
r = pixel And 255
g = (pixel >> 8) And 255
b = (pixel >> 16) And 255
'brightness calculation
'shift right by 10 <=> divide by 1024
r = (r * mult) >> 10
g = (g * mult) >> 10
b = (b * mult) >> 10
'clamp to between 0 and 255
If r < 0 Then r = 0
If g < 0 Then g = 0
If b < 0 Then b = 0
r = (r And 255)
g = (g And 255)
b = (b And 255)
pixels(i) = r Or (g << 8) Or (b << 16) Or &HFF000000
Next
End Sub
Vous remarquerez peut-être que j'ai utilisé une petite astuce pour éviter de faire des calculs en virgule flottante dans la boucle. Cela améliore considérablement les performances. Et lorsque vous avez terminé, vous devez bien sûr faire un peu de ménage...
addr = IntPtr.Zero
If handle.IsAllocated Then
handle.Free()
handle = Nothing
End If
bitmap.Dispose()
bitmap = Nothing
pixels = Nothing
J'ai ignoré la composante alpha ici, mais vous êtes libre de l'utiliser également. J'ai créé de nombreux outils d'édition d'images bitmap de cette manière. C'est beaucoup plus rapide et plus fiable que Bitmap.LockBits() et surtout, cela ne nécessite aucune copie de mémoire pour commencer à éditer votre bitmap.
1 votes
Le lien suivant présente une comparaison des méthodes d'accès aux pixels des images bitmap. csharpexamples.com/fast-image-processing-c