Die optimale Bildschirmübertragung

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Die optimale Bildschirmübertragung

    Hallo.

    Ich möchte eine optimale Bildschirmübertragung entwickeln, das heißt, sie soll sehr effizient sein (vergleichbar zu
    Teamviewer Bildschirmübertragung).

    Dazu benötige ich eure Tipps.

    Derzeit bin ich am vergleichenn der Screens, denn es sollen ja nur die
    Pixel übertragen werden, die sich verändert haben.

    -Parallel.For ist bei meinem Test langsamer gewesen als das normale For , wie kommt das?
    -Was habt ihr generell zum Code zu sagen? Bitte um Verbesserungsvorschläge!



    VB.NET-Quellcode

    1. Option Strict On
    2. Option Infer Off
    3. Imports System.Runtime.InteropServices
    4. Public Class Form1
    5. Private CurrScreenVar As Bitmap
    6. Private Property CurrScreen() As Bitmap
    7. Get
    8. Return CurrScreenVar
    9. End Get
    10. Set(value As Bitmap)
    11. If value.Equals(CurrScreenVar) Then Exit Property
    12. CurrScreenVar = value
    13. End Set
    14. End Property
    15. Private Function TakeScreen() As Bitmap
    16. Dim S As Screen = Screen.PrimaryScreen
    17. Dim B As Bitmap = New Bitmap(S.Bounds.Width, S.Bounds.Height)
    18. Dim G As Graphics = Graphics.FromImage(B)
    19. G.CopyFromScreen(S.Bounds.Left, S.Bounds.Top, 0, 0, S.Bounds.Size)
    20. Return B
    21. End Function
    22. Private Structure BitmapChangeData
    23. Public Sub New(L As Integer, Vall As Short)
    24. AbsoluteIndex = L
    25. Valuee = Vall
    26. End Sub
    27. Public AbsoluteIndex As Long
    28. Public Valuee As Short
    29. End Structure
    30. Private Recto, RectoTwo As Rectangle
    31. Private BiD As New BitmapChangeData
    32. Private Pointz As New List(Of BitmapChangeData)
    33. Private Function CompareScreens(bmp As Bitmap, old As Bitmap) As BitmapChangeData()
    34. If Not bmp.Size.Equals(old.Size) Then Return New BitmapChangeData() {}
    35. Pointz.Clear()
    36. Recto.Size = New Size(bmp.Width, bmp.Height)
    37. RectoTwo.Size = New Size(old.Width, old.Height)
    38. Dim bmpdat As Imaging.BitmapData = bmp.LockBits(Recto, Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
    39. Dim bmpdatTwo As Imaging.BitmapData = old.LockBits(RectoTwo, Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
    40. Dim ptr As IntPtr = bmpdat.Scan0
    41. Dim ptrTwo As IntPtr = bmpdatTwo.Scan0
    42. Dim bytes As Integer = Math.Abs(bmpdat.Stride) * bmp.Height
    43. Dim bytestwo As Integer = Math.Abs(bmpdatTwo.Stride) * old.Height
    44. Dim Rgbz(bytes - 1) As Byte
    45. Dim RgbzTwo(bytestwo - 1) As Byte
    46. Marshal.Copy(ptr, Rgbz, 0, bytes)
    47. Marshal.Copy(ptrTwo, RgbzTwo, 0, bytestwo)
    48. 'Parallel.For(0, Rgbz.Length - 1, Sub(i)
    49. ' If Not Rgbz(i) = RgbzTwo(i) Then
    50. ' BiD.AbsoluteIndex = i
    51. ' BiD.Valuee = Rgbz(i)
    52. ' Pointz.Add(BiD)
    53. ' End If
    54. ' End Sub)
    55. For i As Integer = 0 To Rgbz.Length - 1
    56. If Not Rgbz(i) = RgbzTwo(i) Then
    57. BiD.AbsoluteIndex = i
    58. BiD.Valuee = Rgbz(i)
    59. Pointz.Add(BiD)
    60. End If
    61. Next
    62. Marshal.Copy(Rgbz, 0, ptr, bytes)
    63. Marshal.Copy(RgbzTwo, 0, ptrTwo, bytestwo)
    64. bmp.UnlockBits(bmpdat)
    65. old.UnlockBits(bmpdatTwo)
    66. Return Pointz.ToArray
    67. End Function
    68. Private Async Sub Doit()
    69. Await Task.Run(Sub()
    70. If CurrScreen Is Nothing Then
    71. CurrScreen = TakeScreen()
    72. Me.Invoke(Sub() Me.Text = "First screenshot.")
    73. Else
    74. Dim st As New Stopwatch
    75. st.Start()
    76. Dim k As Bitmap = TakeScreen()
    77. Me.Invoke(Sub() Me.Text = "Veränderte Pixel: " & CompareScreens(k, CurrScreen).Count.ToString)
    78. st.Stop()
    79. MessageBox.Show(st.Elapsed.Milliseconds.ToString)
    80. End If
    81. End Sub)
    82. End Sub
    83. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    84. Doit()
    85. End Sub
    86. End Class
    1. Unterteile dein Bild mit einem Grid und vergleiche/sende nur einzelne Grids
    2. Versuche Marshall.Copy zu verhindern(C# unsafe, frag mich aber nicht wie man das mit VB hinbekommt)
    3. würde ich nur die einzelnen Grids parallel laufen lassen, nicht aber das komplette Überprüfen, ich weiß zwar nicht genau wie Parallel.For arbeitet, aber ich könnte mir vorstellen, dass es Versucht auf mehreren Prozessoren zu arbeiten und das hin und herschicken der Daten zwischen den einzelnen Kernen länger dauert als das überprüfen selbst...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    So wird das kaum was. Du müsstest wenn schon das Bildgeschehen live mit nem Codec wie H.264 hardwarebeschleunigt enkodieren und diesen Stream dann schicken - anders wird das nie was.

    Daniel Baumert schrieb:

    vergleichbar zu Teamviewer
    Dann nimm Teamviewer oder solch.
    Wozu willst Du das Rad neu erfinden?
    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!