kostenloser Webspace werbefrei: lima-city


[C#] Bild per Stream übertragen

lima-cityForumProgrammiersprachenProgrammieren mit .NET & Mono

  1. Autor dieses Themas

    zulman

    zulman hat kostenlosen Webspace.

    Hallo,
    ich habe mir ein kleines Programm gebastelt. mit dem ich eigendlich per Konsole gesteuert einen anderen PC, der den Client gestartet hat (Server steuert den Client) herunterfahren zu können oder zu rebooten. (Keine Angst, soll kein RAT werden, läuft alles Sichtbar ab und das Prog kann geschlossen werden^^, ist eher für mich gedacht, wenn ich gerade an einem anderen PC bin und den PC an dem ich gerade nicht bin herunterfahren will) Nun wollte ich eine Funktion einbauen, die einen Screenshot meines Desktops an den Server überträgt. Nur leider kommt das Bild nur in schlechter Qualität bzw. nur halb an. Hier sind die Codeschnipsel die dazu gehören, vllt könnt ihr mir sagen wo der Fehler liegt. Danke schon mal im Voraus!

    Client:
    Bitmap bild = CaptureScreen(); //CaptureScreen() erstellt einen Screenshot und gibt ihn in Form eines Bitmaps zurück
    MemoryStream IS = new MemoryStream();
    bild.Save(IS, ImageFormat.Jpeg);
    IS.Flush();
    byte[] bildbuffer = IS.ToArray();
    netStream.Write(BitConverter.GetBytes(bildbuffer.Length),0,4);
    netStream.Write(bildbuffer, 0, bildbuffer.Length);


    Server:
    byte[] LengthBytes = new Byte[1000];
    NetworkStream netStream = client.GetStream();
    netStream.Read(LengthBytes,0,4); //Empfängt die Länge des byte Array das das Bild enthält
    int Length;
    Length = BitConverter.ToInt32(LengthBytes,0);
    byte[] Bild = new Byte[Length];
    netStream.Read(Bild, 0, Length); //Empfängt das Bild
    Bitmap img;
    MemoryStream ms = new MemoryStream(Bild);
    img = new Bitmap(ms);
    Console.WriteLine("Screenshot wurde empfangen!");
    Application.Run(new Form1(img, img.Width, img.Height)); // Form1 enthält eine pictureBox. Im Konstruktor wird das Bild anhand der Parameter eingefügt.
    ms.Close();


    mfg
    Zulman
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Was bedeutet es kommt nur in schlechter Qualität an?
  4. Autor dieses Themas

    zulman

    zulman hat kostenlosen Webspace.

    ich stell morgen mal ein Bild rein, wie das dann aussieht. Jetzt ist es leider ein bisschen spät, um das noch zu machen.

    Edit: So, hier ist das Bild. Die weißen Stellen habe ich manuell hin gemacht. Ihr müsst ja nicht alles Wissen :P Also, wie man sieht ist der Anfang des Bildes total in Ordnung und unten auf einmal passt irgend etwas nicht mehr. Die Taskleiste links an der Seite gehört so, falls ihr euch wundert.

    http://www.dpi-up.eu/show.php?file=1266794075.jpg

    Beitrag zuletzt geändert: 21.2.2010 12:37:02 von zulman
  5. Das kann ich mir auch nicht erklären. Vor allem das ein Teil übertragen wird und der andere nciht. Kann leider nicht helfen.
  6. Ich weiß es leider auch nicht, aber ich würde auf jeden Fall beim Client den Memorystream wieder schließen.
    IS.Close()


    Beitrag zuletzt geändert: 21.2.2010 22:25:16 von honliga
  7. Hi,
    ich möchte mal voraus schicken, dass ich in meinem Leben noch keine Zeile C# geschrieben habe, aber irgendwie ist ja doch immer alles ähnlich ;).
    Also in der Zeile
    netStream.Write(BitConverter.GetBytes(bildbuffer.Length),0,4);
    gehst du von einer Länge der Buffergröße von 4 Byte aus, warum? Insbesondere dimensionierst du das korrespondierende Array im Empfänger mit 1000 Bytes. Ich würde also mal diesen Wert 4 auf Client und Serverseite erhöhen und sehen was passiert.
    Wenn ich mir das Beispiel auf http://msdn.microsoft.com/de-de/library/system.net.sockets.tcpclient.getstream.aspx anschaue, würde ich übrigens sagen, dass es gar nicht erforderlich ist die Größe des Arrays mit den Bilddaten zu übertragen (noch dazu als Array), weil der Wert mit
    Client.ReceiveBufferSize
    abgefragt werden kann, wobei der Objektname "Client" natürlich an deinen Code angepasst werden muß.

    Gruß
    Manni
  8. ha, trifft sich ja gut. Ich arbeite grade an einem solchen Programm: :) Hier mal ein ausschnitt aus der FileSend-Funktion.
    Die Funktion ist Teil einer Klasse, kann sein, dass einige Variablen nicht in der Funktion definiert sind.

    void FileSend(string sFileName)
            {
                FileStream oFileStream = new FileStream(sFileName, FileMode.Open);
                FileStream oSendFileStraem = new oFileStream(oFileStream);
                byteBuffer = new byte[oSendFileStream.Length];
                oSendFileStream.Read(byteBuffer, 0, byteBuffer.Length);
                
                oSendNetStreamWriter.Write(sSendFilename);
                oSendNetStreamWriter.Write(oSendFileStream.Length);
                oSendNetStreamWriter.Flush();
    
                int gesamtbytes = byteBuffer.Length;
                int gesendetebytes = 0;
                int restlichebytes = byteBuffer.Length;
    
                while (gesendetebytes < gesamtbytes)
                {
                    if (gesendetebytes > (gesamtbytes - 1024))
                    {
                        oSendNetStream.Write(byteBuffer, gesendetebytes, (gesamtbytes - gesendetebytes));
                    }
                    else
                    {
                        oSendNetStream.Write(byteBuffer, gesendetebytes,1024);
                    }
                    oSendNetStreamWriter.Flush();
                    oSendNetStream.Flush();
                    gesendetebytes = gesendetebytes + 1024;
                }
            }


    und zum Empfangen:

    void Receve(string sRecvFileName)
    {
    FileStream oRecvFileStream = new FileStream(sRecvFileName, FileMode.Create);
                if (sRecvFilename == "" || sRecvFilename == null)
                    sRecvFilename = oSendNetStreamReader.ReadString();
                else
                    oRecvNetStreamReader.ReadString();
                byteBuffer = new byte[oRecvNetStreamReader.ReadInt64()];
    
                int gelesenebytes = 0;
                while (gelesenebytes < byteBuffer.Length)
                {
                    //System.Threading.Thread.Sleep(100);                                   // aus-auskommentieren, wenn er schneller lesen will als senden 
                    if (gelesenebytes > (byteBuffer.Length - 1024))
                    {
                        oRecvNetStream.Read(byteBuffer, gelesenebytes, (byteBuffer.Length - gelesenebytes));
                        oRecvFileStream.Write(byteBuffer, gelesenebytes, (byteBuffer.Length - gelesenebytes));
                    }
                    else
                    {
                        oRecvNetStream.Read(byteBuffer, gelesenebytes, 1024);
                        oRecvFileStream.Write(byteBuffer, gelesenebytes, 1024);
                    }
    
                    oRecvFileStream.Flush();
                    gelesenebytes = gelesenebytes + 1024;
                }
            }


    Hoffe das geht jetzt so... musste sie etwas verändern, soll ja auch ohne Klasse funktionieren. Wenn nicht melde dich nochmal^^
    Die Networkstreams musst du die selber besorgen, wenn du TcpSocket/-Listener nutzt, kannst du über GetStream(); die Stream bekommen.
    Hoffe es hilft dir weiter.

    PS: Dein Fehler ist, dass du zu viele Bytes in den NetworkStream schreiben willst, das Problem hatte ich auch schon.

    Beitrag zuletzt geändert: 28.2.2010 15:54:25 von primenic
  9. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!