Zeichenfläche TCanvas über das Netzwerk versenden
-
Hmmm, ohne Quellcode wird das glaube ich nichts auf diesem Wege.
Speichere die Canvas erst mal zwischen und versende das Bild z.B. als Bitmap.
Wenn der Client das Bild empfängt und es sich auch manuell öffnen lässt, weisst Du, dass es nicht an der Übertragung liegt.Oder Du postet mal ein bisschen mehr Code.
Habe sowas selber mal gemacht. Vielleicht hilft es Dir ja weiter:
// Screenshot vom aktuellen Bildschirm schiessen HDC dc = GetDC(NULL); Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas(); ScreenCanvas->Handle = dc; Image1->AutoSize = true; Image1->Center = true; Image1->Top = 0; Image1->Left = 0; Image1->Picture->Bitmap->Width = Settings.DesktopImage.XAufloesung; Image1->Picture->Bitmap->Height = Settings.DesktopImage.YAufloesung; TRect rectSource = Rect(0,0,Screen->Width, Screen->Height); TRect rectDest = Rect(0,0,Settings.DesktopImage.XAufloesung, Settings.DesktopImage.YAufloesung); Image1->Picture->Bitmap->Canvas->CopyRect(rectDest, ScreenCanvas, rectSource);und das ganze dann als JPEG via FastNet versenden:
TJPEGImage *jp = new TJPEGImage(); try { jp->Assign(Image1->Picture->Bitmap); jp->CompressionQuality = Settings.DesktopImage.Bildqualitaet; jp->PixelFormat = jf24Bit; jp->ProgressiveDisplay = true; jp->ProgressiveEncoding = true; jp->Smoothing = true; jp->Compress(); jp->SaveToFile("test.jpg"); } __finally { delete jp; } TFileStream *MyFStream; MyFStream = new TFileStream("test.jpg", fmOpenRead); try { NMStrm1->Host = Parameter; NMStrm1->FromName = "GetDesktopImage:" + IntToStr(Screen->Width); NMStrm1->PostIt(MyFStream); } catch(...) { } MyFStream->Free();PS: Bei mir gab es damals Probleme, dass die Canvas' verschiedene Grössen hatten
-
ich habe hier noch etwas getestet..
hier überträgst speicherst du einfach das Array von TColors für jedes Pixel ab und lädst es wieder:void __fastcall TForm1::Button1Click(TObject *Sender) { Image1->Canvas->Brush->Color = clRed; Image1->Canvas->FillRect(Image1->ClientRect); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { TCanvas *can = Image1->Canvas; TFileStream *Stream = new TFileStream("C:\\temp\\canvas_test.bin",fmCreate); TRect Rect = can->ClipRect; for(int x = 0; x < Rect.Width(); x++) { for(int y = 0; y < Rect.Height(); y++) { int iSize = sizeof(can->Pixels[x][y]); //TColor ist soviel ich weiss immer 4 Byte gross TColor Color = can->Pixels[x][y]; Stream->Write((void*)&Color,iSize); } } delete Stream; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { TCanvas *can = Image2->Canvas; TFileStream *Stream = new TFileStream("C:\\temp\\canvas_test.bin",fmOpenRead); TRect Rect = can->ClipRect; for(int x = 0; x < Rect.Width(); x++) { for(int y = 0; y < Rect.Height(); y++) { TColor Color; Stream->Read(&Color,4); //TColor ist soviel ich weiss immer 4 Byte gross can->Pixels[x][y] = Color; } } delete Stream; Image2->Repaint(); } //---------------------------------------------------------------------------jedoch ist der Code bestimmt nicht Perfekt und sollte dringenst noch überarbeitet werden. zB könnte man am anfang noch das ClientRect speichern etc..
evtl dient es etwas als Anregung
-
moin!
Vielen Dank für eure Hilfestellung.
Ist es möglich meinen Code um ein paar Zeilen zu erweitern damit man kurzfristig die TCanvas Zeichenfläche zwischenspeichern kann, damit man dann die Zeichenfläche versendet und nicht den Zeiger. Ich hab leider noch zu wenig Ahnung und bekomme einfach mittlerweile keine Idee mehr. Ist bisher alles gescheitert. Die Quellcodes helfen mir dabei leider auch nicht viel weiter, trozdem vielen Dank.
-
Hallo
Am einfachsten kannst Du die Canvas Speichern indem Du sie in ein Image kopierst und dieses dann in einer Datei speicherst.
// Code ist nicht getestet! Image1->Canvas = YourCanvas; Image1->Picture->SaveToFile("C:\\test.bmp");Diese Datei kannst Du dann mit dem Code, den ich vorher gepostet habe, versenden.
Gruss
-
Ich habe das Problem das der Server den Screenshot machen soll aber komplett im Hintergrund läuft. Und somit auch kein TImage haben soll wo er es reinspeichert. Er soll es wenn möglich auch nicht auf die Fetsplatte zwischenspeichern. Am liebsten wäre mir das er es in eine Variable zwischenspeichert die Variablle dann an den Client versendet.
-
Hallo
und zwar eine Variable vom Typ TBitmap.
bis bald
akari
-
Ich weiß einfach nicht wie, vieleicht könnte mir einer meinen Code berichtigen. Ich habe bisher einfach noch zu wenig Erfahrung und bin mittlerweile am verzweifeln.
Server
----------------------------------------------------------------------
TCanvas* canvas = new TCanvas();
canvas->Handle = GetWindowDC(GetDesktopWindow());
TBitmap canvas2 = canvas; //???????? wie ?????
ServerSocket1->Socket->Connections[0]->SendBuf((canvas2), sizeof(canvas2));Client
----------------------------------------------------------------------
TCanvas* test = new TCanvas();
TRect Dest = Image1->ClientRect;
TBitmap test2 = canvas; //??? wie ????
TRect Source = Rect(0, 0, 1024, 768);
Socket->ReceiveBuf(test2,sizeof(test2));
Image1->Canvas->CopyRect(Dest, test2, Source);
-
Der Code zum senden sollte in etwa so aussehen:
ClientSocket1->Active = true; Graphics::TBitmap *Image1 = new Graphics::TBitmap(); HDC dc = GetDC(NULL); Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas(); ScreenCanvas->Handle = dc; Image1->Width = Screen->Width; Image1->Height = Screen->Height; TRect rectSource = Rect(0,0,Screen->Width, Screen->Height); TRect rectDest = Rect(0,0,Screen->Width, Screen->Height); Image1->Canvas->CopyRect(rectDest, ScreenCanvas, rectSource); Pic->Picture->Bitmap = Image1; // nur zum testen Pic->Picture->SaveToFile("C:\\test.bmp"); // - " - for(int x = 0; x <= ServerSocket1->Socket->ActiveConnections - 1; x++) { ServerSocket1->Socket->Connections[0]->SendBuf((Image1), sizeof(Image1)); } delete Image1; delete ScreenCanvas;
-
Jo vielen Dank das Hilft mir schon um einiges weiter. Hab jetzt nur noch eine Frage und das betrifft das Empfangen.
Client:
Socket->ReceiveBuf(Image1,sizeof(Image1));ODER
TRect Dest = Image1->ClientRect; TRect Source = Rect(0, 0, 1024, 768); TImage* test = new TImage(); //FEHLER Socket->ReceiveBuf(test,sizeof(test)); Image1->Canvas->CopyRect(Dest, Image1, Source);so funktzioniert das leider nicht. Das Image1 bleibt leer. Beim zweiten Beispiel bekomme ich eine Fehlermeldung.
Verzeiht mir meine Unwissenheit, ich schäme mich schon deswegen.
-
LarryXS schrieb:
Client:
TImage* test = new TImage(); //FEHLER Socket->ReceiveBuf(test,sizeof(test)); Image1->Canvas->CopyRect(Dest, Image1, Source);Du musst den Parent angeben, also Deine Form:
TImage* test = new TImage(Form1);weiterhin macht
Socket->ReceiveBuf(test,sizeof(test));keinen Sinn. Was nützt Dir sizeof test, welches Du eben erst intialisiert hast?
Wenn schon, dannSocket->ReceiveBuf(client, Socket->ReceiveLength());.
Um ehrlich zu sein, hänge ich ebenfalls gerade am Empfangen etwas fest. Muss nochmal schauen...
-
Bei sowas kann es nie schaden, sich den FAQ-Eintrag zur Protokollentwicklung anzusehen.
-
Ich habe längere Zeit die FAQ-Beiträge durchstöbert.
Das mit der Protokollentwicklung hilft mir nicht weiter. Für den Text den ich auch über den Client- Serverprogramm habe ich bereits ein Protokoll geschrieben. Das Protokoll soll natürlich auch Anwendung für den Bilderversand haben. Das Problenm ist nur wie ich das Bild in ein string umwandle um die Protokollinforationen anzuhängen. Das andere Problem ist den string am Clientprogramm wider in eine Bitmap umzuwandeln und ins TImage schreibe zu schreiben.