Weg um Colormatrixvorgang zu beschleunigen?

  • Allgemein

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Gather.

    Weg um Colormatrixvorgang zu beschleunigen?

    Hallo liebe Community,
    ich spiele mich derzeit etwas mit der Colormatrix-Klasse in .NET herum,
    und frage mich deswegen ob man diesen Vorgang etwas beschleunigen kann.

    Meine derzeitige Vorgehensweise ist:

    VB.NET-Quellcode

    1. Public Shared Function CompleteColorMatrix(ByVal b As Bitmap, ByVal cm As System.Drawing.Imaging.ColorMatrix) As Bitmap
    2. Using ia As New System.Drawing.Imaging.ImageAttributes
    3. ia.SetColorMatrix(cm)
    4. Dim rc As New Rectangle(0, 0, b.Width, b.Height)
    5. Using bClone As Bitmap = DirectCast(b.Clone, Bitmap)
    6. Using g As Graphics = Graphics.FromImage(b)
    7. g.Clear(Color.Transparent)
    8. g.DrawImage(bClone, rc, 0, 0, bClone.Width, bClone.Height, GraphicsUnit.Pixel, ia)
    9. g.Dispose()
    10. End Using
    11. End Using
    12. End Using
    13. Return b
    14. End Function
    15. ''' <summary>
    16. ''' Uses the bluescale-filter at a given bitmap.
    17. ''' </summary>
    18. ''' <param name="b">The given bitmap.</param>
    19. ''' <returns>Bitmap</returns>
    20. ''' <remarks></remarks>
    21. Public Shared Function BlueScale(ByVal b As Bitmap) As Bitmap
    22. Dim cm As New System.Drawing.Imaging.ColorMatrix(New Single()() _
    23. {New Single() {0, 0, 1, 0, 0}, _
    24. New Single() {0, 1, 0, 0, 0}, _
    25. New Single() {1, 0, 0, 0, 0}, _
    26. New Single() {0, 0, 0, 1, 0}, _
    27. New Single() {0, 0, 0, 0, 1}})
    28. Return CompleteColorMatrix(b, cm)
    29. End Function


    Diese Methode dauert doch eine halbe Sekunde bis Sekunde (+).
    Danke im Vorraus.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Warum nicht so?

    VB.NET-Quellcode

    1. Public Shared Function CompleteColorMatrix(ByVal b As Bitmap, ByVal cm As System.Drawing.Imaging.ColorMatrix) As Bitmap
    2. Dim bClone As New Bitmap(b.Width, b.Height)
    3. Dim rect As New Rectangle(0, 0, b.Width, b.Height)
    4. Using ia As New System.Drawing.Imaging.ImageAttributes
    5. ia.SetColorMatrix(cm)
    6. Using g As Graphics = Graphics.FromImage(bClone)
    7. g.Clear(Color.Transparent)
    8. g.DrawImage(b, rect, 0, 0, b.Width, b.Height, GraphicsUnit.Pixel, ia)
    9. g.Dispose()
    10. End Using
    11. End Using
    12. Return bClone
    13. End Function

    Edit: uups, kleiner Fail, muss natürlich Graphics.FromImage(bClone) heißen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

    Weil es A. Nicht funktioniert,
    und B. genau so schnell wäre (denke ich :) )
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Artentus schrieb:

    Ach wirklich, was funktioniert denn nicht?

    Es passiert nichts. Keine Fehlermeldung. Kein Ergebnis.

    Artentus schrieb:

    Aber das ist GDI, allzu schnell ist das eh nicht, damit musst du leben.

    Da hast du natürlich recht ^^.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Danke, dennoch habe ich absichtlich nicht WPF gewählt, da ich ein bisschen mit Funktionen und GDI herumspiele.

    Artentus schrieb:

    Du hast aber schon meinen Edit gesehen?

    Natürlich. :

    VB.NET-Quellcode

    1. Public Shared Function CompleteColorMatrixnew(ByVal b As Bitmap, ByVal cm As System.Drawing.Imaging.ColorMatrix) As Bitmap
    2. Dim bClone As New Bitmap(b.Width, b.Height)
    3. Dim rect As New Rectangle(0, 0, b.Width, b.Height)
    4. Using ia As New System.Drawing.Imaging.ImageAttributes
    5. ia.SetColorMatrix(cm)
    6. Using g As Graphics = Graphics.FromImage(bClone)
    7. g.Clear(Color.Transparent)
    8. g.DrawImage(b, rect, 0, 0, b.Width, b.Height, GraphicsUnit.Pixel, ia)
    9. g.Dispose()
    10. End Using
    11. End Using
    12. Return bClone
    13. End Function
    14. Public Shared Function ColorFilter(ByVal b As Bitmap, ByVal eColorfilter As eColorFilter) As Bitmap
    15. Dim cm As New System.Drawing.Imaging.ColorMatrix
    16. Select Case eColorfilter
    17. Case Filters.eColorFilter.Red
    18. cm = New System.Drawing.Imaging.ColorMatrix(New Single()() _
    19. {New Single() {1, 0, 0, 0, 0}, _
    20. New Single() {0, 0, 0, 0, 0}, _
    21. New Single() {0, 0, 0, 0, 0}, _
    22. New Single() {0, 0, 0, 1, 0}, _
    23. New Single() {0, 0, 0, 0, 1}})
    24. End Case
    25. Return CompleteColorMatrixNew(b, cm)
    26. End Function


    Edit://
    Dennoch, vielleicht wage ich endlich den Umstieg 100%igen Umstieg auf WPF ^^
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    @Artentus
    Ich bekomme das unveränderte Bild.
    Rufe ich die Methode Falsch auf?

    VB.NET-Quellcode

    1. Dim bb As New Bitmap("D:\Icons\bonus\icons-shadowless-32\balloon.png")
    2. 'Form Load:
    3. PictureBox1.Image = bb
    4. 'Button
    5. BitmapClasses.Filters.ColorFilter(bb, BitmapClasses.Filters.eColorFilter.Red) 'Andere Methode, selber Inhalt
    6. PictureBox1.Image = bb
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Gather“ ()

    Haha ja das stimmt natürlich ^^ Komplett falsch geschrieben :O
    Jop, logischerweise klappt es jetzt. Dennoch an der Geschwindigkeit änderz sich nichts. Dauert beides 19-20 Millisekunden.

    Kann man wohl nichts machen.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Gather“ ()

    @Gather:: Sehe ich das richtig? Du willst RGB-Kanäle tauschen?
    Am besten wäre es natürlich Unsave in C#, aber auch in VB geht es so:
    Locke die Bits, hole sie in ein Byte-Array, tausche die Elemente von Hand und zurück.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi
    hab' mal 'ne Testoptimierung gemacht. Die ist auf meinem PC zumindest nicht effizienter gewesen, als die ColorMatrix selber, aber ich fand es an sich interessant:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Imports System.Reflection.Emit
    3. Imports System.Drawing.Imaging
    4. Imports System.Reflection
    5. Public Structure Fixed32
    6. Implements IEquatable(Of Fixed32)
    7. Public Shared ReadOnly MinValue As Fixed32 = New Fixed32(Integer.MinValue)
    8. Public Shared ReadOnly MaxValue As Fixed32 = New Fixed32(Integer.MaxValue)
    9. Public Shared ReadOnly Epsilon As Fixed32 = New Fixed32(1)
    10. Private _value As Integer
    11. Public Shared Operator *(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    12. Return New Fixed32(CInt(Math.BigMul(left._value, right._value) >> 32))
    13. End Operator
    14. Public Shared Operator /(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    15. Return New Fixed32(CInt((CLng(left._value) << 16) \ right._value))
    16. End Operator
    17. Public Shared Operator -(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    18. Return New Fixed32(left._value - right._value)
    19. End Operator
    20. Public Shared Operator +(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    21. Return New Fixed32(left._value + right._value)
    22. End Operator
    23. Public Shared Operator And(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    24. Return New Fixed32(left._value And right._value)
    25. End Operator
    26. Public Shared Operator Or(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    27. Return New Fixed32(left._value Or right._value)
    28. End Operator
    29. Public Shared Operator Xor(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    30. Return New Fixed32(left._value Xor right._value)
    31. End Operator
    32. Public Shared Operator <<(ByVal left As Fixed32, ByVal right As Integer) As Fixed32
    33. Return New Fixed32(left._value << right)
    34. End Operator
    35. Public Shared Operator >>(ByVal left As Fixed32, ByVal right As Integer) As Fixed32
    36. Return New Fixed32(left._value >> right)
    37. End Operator
    38. Public Shared Operator =(ByVal left As Fixed32, ByVal right As Fixed32) As Boolean
    39. Return left._value = right._value
    40. End Operator
    41. Public Shared Operator <>(ByVal left As Fixed32, ByVal right As Fixed32) As Boolean
    42. Return left._value <> right._value
    43. End Operator
    44. Public Shared Operator <(ByVal left As Fixed32, ByVal right As Fixed32) As Boolean
    45. Return left._value < right._value
    46. End Operator
    47. Public Shared Operator >(ByVal left As Fixed32, ByVal right As Fixed32) As Boolean
    48. Return left._value > right._value
    49. End Operator
    50. Public Shared Operator <=(ByVal left As Fixed32, ByVal right As Fixed32) As Boolean
    51. Return left._value <= right._value
    52. End Operator
    53. Public Shared Operator >=(ByVal left As Fixed32, ByVal right As Fixed32) As Boolean
    54. Return left._value >= right._value
    55. End Operator
    56. Public Shared Operator Mod(ByVal left As Fixed32, ByVal right As Fixed32) As Fixed32
    57. Return New Fixed32(left._value Mod right._value)
    58. End Operator
    59. Public Shared Operator Not(ByVal value As Fixed32) As Fixed32
    60. Return New Fixed32(Not value._value)
    61. End Operator
    62. Public Shared Operator +(ByVal value As Fixed32) As Fixed32
    63. Return value
    64. End Operator
    65. Public Shared Operator -(ByVal value As Fixed32) As Fixed32
    66. Return New Fixed32(-value._value)
    67. End Operator
    68. Private Sub New(ByVal value As Integer)
    69. _value = value
    70. End Sub
    71. Public Shared Widening Operator CType(ByVal value As Short) As Fixed32
    72. Return New Fixed32(CInt(value) << 16)
    73. End Operator
    74. Public Shared Narrowing Operator CType(ByVal value As Fixed32) As Short
    75. Return CShort(value._value >> 16)
    76. End Operator
    77. Public Shared Narrowing Operator CType(ByVal value As Integer) As Fixed32
    78. Return New Fixed32(value * (1 << 16))
    79. End Operator
    80. Public Overrides Function GetHashCode() As Integer
    81. Return _value
    82. End Function
    83. Public Overrides Function Equals(ByVal obj As Object) As Boolean
    84. Return obj IsNot Nothing AndAlso TypeOf obj Is Fixed32 AndAlso Equals(DirectCast(obj, Fixed32))
    85. End Function
    86. Public Overloads Function Equals(ByVal other As Fixed32) As Boolean Implements System.IEquatable(Of Fixed32).Equals
    87. Return _value = other._value
    88. End Function
    89. Public Overrides Function ToString() As String
    90. Dim output As New System.Text.StringBuilder()
    91. Dim cv As Integer = _value
    92. output.Append(cv >> 16)
    93. cv = cv And &HFFFF
    94. If cv <> 0 Then
    95. output.Append(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator)
    96. Do
    97. cv *= 10
    98. output.Append(cv >> 16)
    99. cv = cv And &HFFFF
    100. Loop While cv > 0
    101. End If
    102. Return output.ToString()
    103. End Function
    104. Public Shared Function GetRaw(ByVal value As Fixed32) As Integer
    105. Return value._value
    106. End Function
    107. Public Shared Function FromRaw(ByVal value As Integer) As Fixed32
    108. Return New Fixed32(value)
    109. End Function
    110. End Structure
    111. Public Structure Matrix4x4
    112. 'use c# unsafe fixed here and explicit layout
    113. Public M11, M12, M13, M14,
    114. M21, M22, M23, M24,
    115. M31, M32, M33, M34,
    116. M41, M42, M43, M44 As Fixed32
    117. Public ReadOnly Property IsIdentity As Boolean
    118. Get
    119. Return M11 = 1S AndAlso M12 = 0S AndAlso M13 = 0S AndAlso M14 = 0S AndAlso _
    120. M21 = 0S AndAlso M22 = 1S AndAlso M23 = 0S AndAlso M24 = 0S AndAlso _
    121. M31 = 0S AndAlso M32 = 0S AndAlso M33 = 1S AndAlso M34 = 0S AndAlso _
    122. M41 = 0S AndAlso M42 = 0S AndAlso M43 = 0S AndAlso M44 = 1S
    123. End Get
    124. End Property
    125. 'implement operators
    126. Public Sub New(ByVal m11 As Fixed32, ByVal m12 As Fixed32, ByVal m13 As Fixed32, ByVal m14 As Fixed32,
    127. ByVal m21 As Fixed32, ByVal m22 As Fixed32, ByVal m23 As Fixed32, ByVal m24 As Fixed32,
    128. ByVal m31 As Fixed32, ByVal m32 As Fixed32, ByVal m33 As Fixed32, ByVal m34 As Fixed32,
    129. ByVal m41 As Fixed32, ByVal m42 As Fixed32, ByVal m43 As Fixed32, ByVal m44 As Fixed32)
    130. Me.M11 = m11 : Me.M12 = m12 : Me.M13 = m13 : Me.M14 = m14
    131. Me.M21 = m21 : Me.M22 = m22 : Me.M23 = m23 : Me.M24 = m24
    132. Me.M31 = m31 : Me.M32 = m32 : Me.M33 = m33 : Me.M34 = m34
    133. Me.M41 = m41 : Me.M42 = m42 : Me.M43 = m43 : Me.M44 = m44
    134. End Sub
    135. Public Shared Function FromInt32(ByVal m11 As Integer, ByVal m12 As Integer, ByVal m13 As Integer, ByVal m14 As Integer,
    136. ByVal m21 As Integer, ByVal m22 As Integer, ByVal m23 As Integer, ByVal m24 As Integer,
    137. ByVal m31 As Integer, ByVal m32 As Integer, ByVal m33 As Integer, ByVal m34 As Integer,
    138. ByVal m41 As Integer, ByVal m42 As Integer, ByVal m43 As Integer, ByVal m44 As Integer) As Matrix4x4
    139. Return New Matrix4x4(CType(m11, Fixed32), CType(m12, Fixed32), CType(m13, Fixed32), CType(m14, Fixed32),
    140. CType(m21, Fixed32), CType(m22, Fixed32), CType(m23, Fixed32), CType(m24, Fixed32),
    141. CType(m31, Fixed32), CType(m32, Fixed32), CType(m33, Fixed32), CType(m34, Fixed32),
    142. CType(m41, Fixed32), CType(m42, Fixed32), CType(m43, Fixed32), CType(m44, Fixed32))
    143. End Function
    144. End Structure
    145. Public Class QuickColorMatrix
    146. Private ReadOnly _handler As Action(Of Integer(), Integer, Integer)
    147. Public Sub New(ByVal colorMatrix As Matrix4x4)
    148. _handler = DefineMethod(colorMatrix)
    149. End Sub
    150. Private Shared Function DefineMethod(ByVal colorMatrix As Matrix4x4) As Action(Of Integer(), Integer, Integer)
    151. If colorMatrix.IsIdentity Then Return Nothing
    152. Dim matrix(15) As Integer
    153. 'unsafe <3
    154. Dim gch As GCHandle = GCHandle.Alloc(colorMatrix, GCHandleType.Pinned)
    155. Marshal.Copy(gch.AddrOfPinnedObject(), matrix, 0, matrix.Length)
    156. gch.Free()
    157. Dim method As New DynamicMethod(String.Empty, GetType(Void), New Type() {GetType(Integer()), GetType(Integer), GetType(Integer)}, GetType(QuickColorMatrix).Module, True)
    158. Dim ilg As ILGenerator = method.GetILGenerator()
    159. ilg.DeclareLocal(GetType(Integer).MakePointerType(), True) 'currentPtr
    160. ilg.DeclareLocal(GetType(Integer).MakePointerType()) 'destPtr
    161. ilg.DeclareLocal(GetType(Integer)) 'currentChannel
    162. ilg.DeclareLocal(GetType(Integer)) 'currentValue
    163. ilg.DeclareLocal(GetType(Long)) 'a
    164. ilg.DeclareLocal(GetType(Long)) 'r
    165. ilg.DeclareLocal(GetType(Long)) 'g
    166. ilg.DeclareLocal(GetType(Long)) 'b
    167. ilg.DeclareLocal(GetType(Integer()), True)
    168. Dim initialized(3) As Boolean
    169. Dim cond As Label = ilg.DefineLabel()
    170. Dim bodyEnd As Label = ilg.DefineLabel()
    171. 'currentPtr = parameters[0] (pointer to array)
    172. ilg.Emit(OpCodes.Ldarg_0)
    173. ilg.Emit(OpCodes.Stloc_S, CByte(8))
    174. ilg.Emit(OpCodes.Ldloc_S, CByte(8))
    175. ilg.Emit(OpCodes.Ldc_I4_0)
    176. ilg.Emit(OpCodes.Ldelema, GetType(Integer))
    177. ilg.Emit(OpCodes.Ldarg_1)
    178. ilg.Emit(OpCodes.Add)
    179. ilg.Emit(OpCodes.Stloc_0)
    180. 'get end pointer
    181. ilg.Emit(OpCodes.Ldloc_0)
    182. ilg.Emit(OpCodes.Ldarg_2)
    183. ilg.Emit(OpCodes.Ldc_I4_2)
    184. ilg.Emit(OpCodes.Shl)
    185. ilg.Emit(OpCodes.Add)
    186. ilg.Emit(OpCodes.Stloc_1)
    187. ilg.MarkLabel(cond)
    188. 'if current < dest is not true then go to end
    189. ilg.Emit(OpCodes.Ldloc_0)
    190. ilg.Emit(OpCodes.Ldloc_1)
    191. ilg.Emit(OpCodes.Bge, bodyEnd)
    192. 'load value at address and store it in currentValue
    193. ilg.Emit(OpCodes.Ldloc_0)
    194. ilg.Emit(OpCodes.Ldind_I4)
    195. ilg.Emit(OpCodes.Stloc_3)
    196. 'apply matrix multiplication, where required, skip additions of 0 and multiplication by 1
    197. For column As Integer = 0 To 3
    198. Dim ci As Byte = CByte(4 + column)
    199. Dim used As Boolean = False
    200. 'extract channel value
    201. ilg.Emit(OpCodes.Ldloc_3)
    202. If column <> 3 Then 'skip bitshift where not required
    203. ilg.Emit(OpCodes.Ldc_I4_S, CByte((3 - column) * 8))
    204. ilg.Emit(OpCodes.Shr_Un)
    205. End If
    206. If column <> 0 Then 'skip mask where not required
    207. ilg.Emit(OpCodes.Ldc_I4, 255)
    208. ilg.Emit(OpCodes.And)
    209. End If
    210. ilg.Emit(OpCodes.Stloc_2) 'store local channel
    211. For row As Integer = 0 To 3
    212. Dim ccell As Integer = matrix(row * 4 + column)
    213. If ccell <> 0 Then 'skip values of 0
    214. ilg.Emit(OpCodes.Ldloc_2)
    215. ilg.Emit(OpCodes.Conv_I8)
    216. If ccell <> &H10000 Then 'skip multiplication for values of 1
    217. ilg.Emit(OpCodes.Ldc_I8, CLng(ccell))
    218. ilg.Emit(OpCodes.Mul)
    219. Else
    220. ilg.Emit(OpCodes.Ldc_I4_S, CByte(16))
    221. ilg.Emit(OpCodes.Shl)
    222. End If
    223. If initialized(row) Then 'skip addition if the value has not been initialized
    224. ilg.Emit(OpCodes.Add)
    225. Else
    226. initialized(row) = True
    227. End If
    228. used = True
    229. End If
    230. Next
    231. If used Then ilg.Emit(OpCodes.Stloc_S, ci)
    232. Next
    233. Dim elsepart As Label
    234. Dim endifcond As Label
    235. ilg.Emit(OpCodes.Ldloc_0) 'push address for later use
    236. For i As Integer = 0 To 3
    237. endifcond = ilg.DefineLabel()
    238. elsepart = ilg.DefineLabel()
    239. 'get, limit and combine values
    240. ilg.Emit(OpCodes.Ldloc_S, CByte(7 - i))
    241. ilg.Emit(OpCodes.Ldc_I4_S, CByte(16))
    242. ilg.Emit(OpCodes.Shr)
    243. ilg.Emit(OpCodes.Conv_I4)
    244. ilg.Emit(OpCodes.Dup)
    245. ilg.Emit(OpCodes.Stloc_2)
    246. 'clip 0
    247. 'if (value < 0)
    248. ilg.Emit(OpCodes.Ldc_I4_0)
    249. ilg.Emit(OpCodes.Bge, elsepart)
    250. 'load 0
    251. 'TODO: skip | if i > 0, otherwise push 0
    252. ilg.Emit(OpCodes.Ldc_I4_0)
    253. ilg.Emit(OpCodes.Br, endifcond)
    254. 'clip 0xff
    255. ilg.MarkLabel(elsepart)
    256. elsepart = ilg.DefineLabel()
    257. 'else if (value > 255)
    258. ilg.Emit(OpCodes.Ldloc_2)
    259. ilg.Emit(OpCodes.Ldc_I4, 255)
    260. ilg.Emit(OpCodes.Blt, elsepart)
    261. 'load 0xff
    262. ilg.Emit(OpCodes.Ldc_I4, 255)
    263. ilg.Emit(OpCodes.Br, endifcond)
    264. 'else
    265. ilg.MarkLabel(elsepart)
    266. 'load value
    267. ilg.Emit(OpCodes.Ldloc_2)
    268. ilg.MarkLabel(endifcond)
    269. If i > 0 Then
    270. ilg.Emit(OpCodes.Ldc_I4_S, CByte(i * 8))
    271. ilg.Emit(OpCodes.Shl)
    272. ilg.Emit(OpCodes.Or)
    273. End If
    274. Next
    275. 'store color (address has been pushed before the value evaluation)
    276. ilg.Emit(OpCodes.Stind_I4)
    277. 'increment current ptr
    278. ilg.Emit(OpCodes.Ldloc_0)
    279. ilg.Emit(OpCodes.Ldc_I4_4)
    280. ilg.Emit(OpCodes.Add)
    281. ilg.Emit(OpCodes.Stloc_0)
    282. 'go to condition
    283. ilg.Emit(OpCodes.Br, cond)
    284. ilg.MarkLabel(bodyEnd)
    285. ilg.Emit(OpCodes.Ret)
    286. Return DirectCast(method.CreateDelegate(GetType(Action(Of Integer(), Integer, Integer))), Action(Of Integer(), Integer, Integer))
    287. End Function
    288. Public Sub Apply(ByVal bitmap As Bitmap)
    289. If bitmap Is Nothing Then Throw New ArgumentNullException("bitmap")
    290. If _handler Is Nothing Then Return
    291. Dim target(bitmap.Width * bitmap.Height - 1) As Integer
    292. Dim targetHandle As GCHandle = GCHandle.Alloc(target, GCHandleType.Pinned)
    293. Dim data As BitmapData = Nothing
    294. Try
    295. data = bitmap.LockBits(New Rectangle(Point.Empty, bitmap.Size), _
    296. ImageLockMode.UserInputBuffer Or ImageLockMode.ReadWrite, _
    297. PixelFormat.Format32bppArgb, _
    298. New BitmapData() With {.Width = bitmap.Width, _
    299. .Height = bitmap.Height, _
    300. .PixelFormat = PixelFormat.Format32bppArgb, _
    301. .Scan0 = targetHandle.AddrOfPinnedObject(), _
    302. .Stride = bitmap.Width * 4})
    303. Apply(target)
    304. Finally
    305. targetHandle.Free()
    306. If data IsNot Nothing Then bitmap.UnlockBits(data)
    307. End Try
    308. End Sub
    309. Public Sub Apply(ByVal target() As Integer)
    310. If target Is Nothing Then Throw New ArgumentNullException("target")
    311. Dim pc As Integer = Environment.ProcessorCount - 1
    312. Dim pid As Integer = target.Length \ pc
    313. System.Threading.Tasks.Parallel.For(0, pc + 1,
    314. Sub(p)
    315. ApplySync(target, pc * p, If(p = pc, target.Length - pc * p, p))
    316. End Sub)
    317. End Sub
    318. Public Sub ApplySync(target() As Integer, startIndex As Integer, count As Integer)
    319. If count < 0 Then Throw New ArgumentException("Non-negative count expected.", "count")
    320. If startIndex < 0 Then Throw New ArgumentException("Non-negative start index expected.", "startIndex")
    321. If startIndex + count > target.Length Then Throw New IndexOutOfRangeException()
    322. If target Is Nothing Then Throw New ArgumentNullException("target")
    323. If _handler IsNot Nothing Then _handler.Invoke(target, startIndex, count)
    324. End Sub
    325. End Class


    Gruß
    ~blaze~
    Ich werds mir dann mal ansehen :D
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!