Bilder senden (fail)

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Kevin Hombre.

    Bilder senden (fail)

    Hi,
    Ich mochte irgendwan eine art "Remptedesktop" schreiben
    Ich möchte aber erstmal einzelne Bilder senden (Will ja klein anfangen)
    Das erstellen der Screens funktioniert soweit ganz gut.
    ich speicher sie als .jpg und ängere dann die Qualität.
    Anschliessend versende ich die bilder dann.

    Ich benutze folgenden code:

    VB.NET-Quellcode

    1. Sub Screenshot(ByVal Qualität As Integer)
    2. Try
    3. Dim Screenshot As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
    4. Dim Graphic As Graphics = Graphics.FromImage(Screenshot)
    5. Graphic.CopyFromScreen(0, 0, 0, 0, Screenshot.Size)
    6. JPEGCompression(Screenshot, My.Computer.FileSystem.SpecialDirectories.Temp & "Screenshot1.jpg", Qualität)
    7. Catch es As Exception
    8. Form1.senden("Fehler beim Erstellen des Screenshots!")
    9. End Try
    10. End Sub
    11. Sub JPEGCompression(ByVal Image As Image, ByVal OutPutFile As String, ByVal Qualität As Integer)
    12. Try
    13. Dim ImageCodecs() As ImageCodecInfo
    14. Dim ImageParameters As EncoderParameters
    15. ImageCodecs = ImageCodecInfo.GetImageEncoders()
    16. ImageParameters = New EncoderParameters(1)
    17. ImageParameters.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, Qualität)
    18. Image.Save(OutPutFile, ImageCodecs(1), ImageParameters)
    19. Senden()
    20. Catch es As Exception
    21. Form1.senden("Fehler beim Komprimieren des Screenshots!")
    22. End Try
    23. End Sub
    24. Sub Senden()
    25. Application.DoEvents()
    26. Dim cli As New TcpClient
    27. cli.Connect("orbitcraft.dyndns.org", 1300)
    28. Try
    29. Dim nstm As Stream = cli.GetStream()
    30. Dim fstm As Stream = New FileStream(My.Computer.FileSystem.SpecialDirectories.Temp & "Screenshot1.jpg", FileMode.Open, FileAccess.Read)
    31. Dim buffer(1024 - 1) As Byte
    32. Do While True
    33. Dim bytesRead As Integer = fstm.Read(buffer, 0, buffer.Length)
    34. If bytesRead = 0 Then Exit Do
    35. nstm.Write(buffer, 0, bytesRead)
    36. nstm.Flush()
    37. Loop
    38. Application.DoEvents()
    39. cli.Close()
    40. nstm.Close()
    41. fstm.Close()
    42. Application.DoEvents()
    43. Catch ex As Exception
    44. Form1.senden("Fehler beim Senden das Screenshots!")
    45. End Try
    46. End Sub


    zum empfangen benutze ich folgenden Code:

    VB.NET-Quellcode

    1. Private Sub ListenSub()
    2. server = New TcpListener(IPAddress.Any, 1300)
    3. server.Start()
    4. Try
    5. While True
    6. Dim c As TcpClient = server.AcceptTcpClient
    7. Dim s As NetworkStream = c.GetStream
    8. FileOpen(1, My.Computer.FileSystem.SpecialDirectories.Temp & "Empfangen", OpenMode.Binary)
    9. Dim buffer(1024 - 1) As Byte
    10. Do While True
    11. Dim bytesRead As Integer = s.Read(buffer, 0, buffer.Length)
    12. If bytesRead = 0 Then Exit Do
    13. FilePut(1, buffer)
    14. Loop
    15. FileClose(1)
    16. s.Close()
    17. c.Close()
    18. Application.DoEvents()
    19. PictureBox1.ImageLocation = My.Computer.FileSystem.SpecialDirectories.Temp & "Empfangen"
    20. End While
    21. Catch ex As Exception
    22. End Try
    23. End Sub


    dabei kommt aber dann sowas raus:



    Was mach ich falsch?
    Da gehen doch irgendwo datenpakete verloren?
    Wie kann ich mich dagegen absichern?

    und ja, ich weiss, dass der code nicht die beste lösung ist, aber für den anfang reicht das mal.
    wie wär's wenn du die daten nicht in eine datei schreibst, sondern gleich das bild überträgst? am besten (in der testphase) vorerst ohne kompression, das dauert dann vmtl. länger aber du könntest sehen, ob das funktioniert.
    Dein ganzer Code ist irgendwie unübersichtlich und "total um die Ecke gedacht" geschrieben.

    Hier mal ein P2P Beispiel , dass du so anpassen kannst, dass es deinen Vorstellungen entspricht:

    Empfangen:

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Net.Sockets, System.IO, System.Net
    3. Module Module1
    4. Dim Reader As BinaryReader
    5. Sub Main()
    6. Dim Listener As TcpListener = New TcpListener(IPAddress.Any, 8008)
    7. Listener.Start()
    8. Console.WriteLine(">> Listener started!")
    9. Console.WriteLine(">> Waiting for tcpclient ...")
    10. While True
    11. Dim Client As TcpClient = Listener.AcceptTcpClient
    12. Reader = New BinaryReader(Client.GetStream)
    13. Console.WriteLine(">> Client connected!")
    14. Receive()
    15. Exit While
    16. End While
    17. End Sub
    18. Private Sub Receive()
    19. Dim FileInfo As String() = Reader.ReadString.Split(CChar("#"))
    20. Console.WriteLine(">> Receiving ...")
    21. Dim B() As Byte = Reader.ReadBytes(CInt(FileInfo(1)))
    22. Console.WriteLine(">> File received.")
    23. Dim Pat As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "received.jpg") ' anstatt received
    24. ' könnte man jetzt auch FileInfo(0) nehmen, denn dort haben wir den Dateinamen ja empfangen.
    25. File.WriteAllBytes(Pat, B)
    26. Console.ReadLine()
    27. End Sub
    28. End Module



    Senden

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Net.Sockets, System.IO
    3. Module Module1
    4. Sub Main()
    5. Dim Client As TcpClient = New TcpClient
    6. Client.Connect("XX.XX.XX.XX", 8008)
    7. Console.WriteLine("Connected!")
    8. Dim Writer As BinaryWriter = New BinaryWriter(Client.GetStream)
    9. Dim Pat As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "ice.jpg")
    10. Dim Tosend() As Byte = File.ReadAllBytes(Pat)
    11. Writer.Write(Path.GetFileName(Pat) & "#" & Tosend.Length)
    12. Console.WriteLine(">> Fileinfo written.")
    13. Console.WriteLine(">> Now we are going to write the bytes")
    14. Writer.Write(Tosend, 0, Tosend.Length)
    15. Console.WriteLine(">> All bytes written.")
    16. Console.ReadLine()
    17. End Sub
    18. End Module



    Hast Du den Post mit dem boundary eigentlich hinbekommen?

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

    Ok, vielen dank, mit dem code funktionierts jetzt problemlos.
    Aber wie lese ich das Comprimierte Bild in Bytearray ein, ohne es vorher zu speichern?
    Also diese 2 zeilen:

    VB.NET-Quellcode

    1. Dim Pat As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "ice.jpg")
    2. Dim Tosend() As Byte = File.ReadAllBytes(Pat)


    Und wie steck ich das Bild in eine Picturebox, ohne es vorher in eine Datei zu schreiben?

    VB.NET-Quellcode

    1. Dim Pat As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "received.jpg") ' anstatt received
    2. ' könnte man jetzt auch FileInfo(0) nehmen, denn dort haben wir den Dateinamen ja empfangen.
    3. File.WriteAllBytes(Pat, B)
    Hey,

    Hier der Code für deine 1. Frage:

    VB.NET-Quellcode

    1. Dim Boundz As Rectangle = Screen.PrimaryScreen.Bounds
    2. Dim SS As Bitmap = New Bitmap(Boundz.Width, Boundz.Height, Imaging.PixelFormat.Format32bppArgb)
    3. Dim Gr As Graphics = Graphics.FromImage(SS)
    4. Gr.CopyFromScreen(Boundz.X, Boundz.Y, 0, 0, Boundz.Size, CopyPixelOperation.SourceCopy)
    5. Dim B As Byte() = Komprimiere(SS)



    Ich hab so etwas schonmal realisiert.

    Du solltest aber bedenken, dass deine Vorgehensweise sehr ineffizient ist.

    Ich kann dir sagen wie ich vorgegangen bin.

    Sagen wir ich bin Client(Cl) , Du Server(Empfänger)(S) , Scr = Screen

    Cl sendet Scr an S
    Cl speichert Scr tempörär

    Cl macht erneut Scr , vergleicht welche Pixel beim neuen Scr anders sind
    Cl rechnet aus, ob sich weniger oder = 38% der Pixel verändert haben
    Haben sich mehr als 38% verändert -> Cl sendet Befehl(auch anhand von Bytes z.B. überall 0) für komplette Dateiübertragung, denn es es ist dann effizienter die ganze Datei zu übertragen
    Haben sich weniger als 38% verändert -> (1) Cl speichert diese Pixelveränderungen zwischen
    (1) Pixel werden in einzelnen Bytes X,y , R, G , B (wenn du schaffst kannste sogar 12bit nehmen) nacheinander an den S übertragen
    S ändert mit der Fastbitmap klasse nur die veränderten Pixel und erhält ein neues Bild.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Anoth3rB0y“ ()

    Ich hab schonmal mit Bitmaps gearbeitet, genauer gesagt berechne ich in einem Programm die Durchschnittsfarbe, indem ich die Bytes in C# durchgehe, deshalb hat mich auch dein Post mit X/Y verwirrt, aber ich sehe, dass ich den Post falsch verstanden hab. ^^
    soweit geht das ganze jetzt, aber was soll das A bie dem RGB?
    Der schlägt mir da immernoch ein A vor.
    Ist das die Transparenz?
    (Aus reinem interesse)

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „simsusim“ ()