Upload TJPEGImage to FTP lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- jjur · 2015-07-09 14:39 Hi, i have this 2 functions in my app. I want to send screenshot (function getscreen) and upload it to ftp. Now it saves screenshot into jpg file in app directory and upload it to ftp. Some computers have problems with permissions, but i don't want to run it with administrator rights. Code: [Select]function ftps(LocalFile : string; remoteFile : string; RemoteDir : string) : boolean; var    rc : boolean;    FTPClient : TFTPSend; begin    // Create the FTP Client object and set the FTP parameters    FTPClient := TFTPSend.Create;    with FTPClient do begin       TargetPort  := '21';       TargetHost := 'my host;        UserName := 'my username';       Password := 'my pass';       //-------------------------------------------------------------- ---------       // bail out if the FTP connect fails       if not LogIn then exit;       //-------------------------------------------------------------- ----------       // Set filename to FTP       DirectFileName := LocalFile;       DirectFile := True;       //-------------------------------------------------------------- ----------       // change directory if requested       if RemoteDir <> '' then ChangeWorkingDir(RemoteDir);       //-------------------------------------------------------------- ----------       // STOR file to FTP server.       rc := StoreFile(RemoteFile,false);       //-------------------------------------------------------------- ----------       // close the connection       LogOut;       //-------------------------------------------------------------- ----------       // free the FTP client object       free;       //-------------------------------------------------------------- ----------    end;    Result := rc; //==================================================================== ======= end; function getscreen(compress: integer; width: integer; height:integer ) : string; var  jpg: TJPEGImage;    ScreenDC: HDC;    temp:string; begin     jpg:=TJPEGImage.Create;   try     jpg.SetSize(Screen.Width, Screen.Height);     ScreenDC := GetDC(0);     try        jpg.LoadFromDevice(ScreenDC);     finally       ReleaseDC(0, ScreenDC);     end;     jpg.CompressionQuality:=compress;     jpg.SaveToFile('file.jpg');     temp:=inttostr(form1.ID) + '_' + DateTimeToStr(Now);     ftps('file.jpg',temp+'.jpg','/');   finally     FreeAndNil(jpg);    getscreen:='http://.../screendata/'+temp+'.jpg';   end;   getscreen:='http://.../screendata/'+temp+'.jpg'; end;  Is possible to upload content of object jpg to ftp without saving image to pc? Thanks ---------------------------------------------------------------------- rvk · 2015-07-09 15:03 Yes. You can use TFTPSend.DataStream. So instead of writing to a file you could create a TMemoryStream. Just do Code: [Select]FTPClient := TFTPSend.Create; try   FTPClient.DataStream := myMemoryStreamWithImage;   // DO NOT SET DirectFile to true !!   // Synapse will use DataStream instead   //... other setup things   rc := FTPClient.StoreFile(RemoteFile,false);   //... etc ---------------------------------------------------------------------- jjur · 2015-07-09 19:47 Hmm, it shows error: Code: [Select]112:function ftps(remoteFile : string; RemoteDir : string; stream: TMemoryStream) : boolean; 113:var 114:   rc : boolean;  115:   FTPClient : TFTPSend; 116:begin 117:   // Create the FTP Client object and set the FTP parameters 118:   FTPClient := TFTPSend.Create; 119:   FTPClient.DataStream := stream; ... unit1.pas(119,25) Error: No member is provided to access property ---------------------------------------------------------------------- rvk · 2015-07-09 19:58 Woops... yes, I see FDataStream is readonly Code: [Select]property DataStream: TMemoryStream read FDataStream; But you can still use it. You should just do a FTPClient.DataStream.LoadFromStream to copy the image to the datastream of the FTPClient: Code: [Select]FTPClient.DataStream.LoadFromStream(stream); Another option would be to first create the FTPClient, then create the image (in memory) and then do: Code: [Select]jpg.SaveToStream(FTPClient.DataStream); then there is no need to an extra stream variable/action. ---------------------------------------------------------------------- jjur · 2015-07-09 20:16 Both raised SIGSEGV  http://snap.ashampoo.com/uploads/2015-07-09/IkKl4INi.png code for first option Code: [Select]function ftps(remoteFile : string; RemoteDir : string; stream: TMemoryStream) : boolean; var    rc : boolean;    FTPClient : TFTPSend; begin    // Create the FTP Client object and set the FTP parameters    FTPClient := TFTPSend.Create;    FTPClient.DataStream.LoadFromStream(stream);    with FTPClient do begin      ....       //-------------------------------------------------------------- ---------       // bail out if the FTP connect fails       if not LogIn then exit;       //-------------------------------------------------------------- ----------       // Set filename to FTP       //DirectFileName := LocalFile;       DirectFile := False;       //-------------------------------------------------------------- ----------       // change directory if requested       if RemoteDir <> '' then ChangeWorkingDir(RemoteDir);       //-------------------------------------------------------------- ----------       // STOR file to FTP server.       rc := StoreFile(RemoteFile,false);       //-------------------------------------------------------------- ----------       // close the connection       LogOut;       //-------------------------------------------------------------- ----------       // free the FTP client object       free;       //-------------------------------------------------------------- ----------    end;    Result := rc; //==================================================================== ======= end; function getscreen(compress: integer; width: integer; height:integer ) : string; var  jpg: TJPEGImage;    ScreenDC: HDC;    temp:string;    stream: TMemoryStream; begin     jpg:=TJPEGImage.Create;   try     jpg.SetSize(Screen.Width, Screen.Height);     ScreenDC := GetDC(0);     try        jpg.LoadFromDevice(ScreenDC);     finally       ReleaseDC(0, ScreenDC);     end;     jpg.CompressionQuality:=compress;     jpg.SaveToStream(stream);     temp:=inttostr(form1.ID) + '_' + DateTimeToStr(Now);     ftps(temp+'.jpg','/',stream);   finally     FreeAndNil(jpg);    getscreen:='http://.../screendata/'+temp+'.jpg';   end;   getscreen:='http://.../screendata/'+temp+'.jpg'; end;    code for second option: Code: [Select]function ftps(remoteFile : string; RemoteDir : string; jpg: TJPEGImage) : boolean; var    rc : boolean;    FTPClient : TFTPSend; begin    // Create the FTP Client object and set the FTP parameters    FTPClient := TFTPSend.Create;    jpg.SaveToStream(FTPClient.DataStream);   // FTPClient.    with FTPClient do begin    ...       if not LogIn then exit;       //-------------------------------------------------------------- ----------       // Set filename to FTP       //DirectFileName := LocalFile;       //DirectFile := False;       //DataStream.LoadFromStream(stream);       //-------------------------------------------------------------- ----------       // change directory if requested       if RemoteDir <> '' then ChangeWorkingDir(RemoteDir);       //-------------------------------------------------------------- ----------       // STOR file to FTP server.       rc := StoreFile(RemoteFile,false);       //-------------------------------------------------------------- ----------       // close the connection       LogOut;       //-------------------------------------------------------------- ----------       // free the FTP client object       free;       //-------------------------------------------------------------- ----------    end;    Result := rc; //==================================================================== ======= end; function getscreen(compress: integer; width: integer; height:integer ) : string; var  jpg: TJPEGImage;    ScreenDC: HDC;    temp:string;    stream: TMemoryStream; begin     jpg:=TJPEGImage.Create;   try     jpg.SetSize(Screen.Width, Screen.Height);     ScreenDC := GetDC(0);     try        jpg.LoadFromDevice(ScreenDC);     finally       ReleaseDC(0, ScreenDC);     end;     jpg.CompressionQuality:=compress;     jpg.SaveToStream(stream);     temp:=inttostr(form1.ID) + '_' + DateTimeToStr(Now);     ftps(temp+'.jpg','/', jpg);   finally     FreeAndNil(jpg);    getscreen:='http://.../screendata/'+temp+'.jpg';   end;   getscreen:='http://.../screendata/'+temp+'.jpg'; end; ---------------------------------------------------------------------- rvk · 2015-07-09 20:42 First of all... it's always wise to mention WHERE those errors occur. Im not sure if you create your TMemoryStream before you do this and how your code now looks but for me it works perfectly. Here is my code: Code: [Select]function ftps(stream: tmemorystream; remoteFile: string; RemoteDir: string): boolean; var   rc: boolean;   FTPClient: TFTPSend; begin   // Create the FTP Client object and set the FTP parameters   FTPClient := TFTPSend.Create;   with FTPClient do   begin     TargetPort := '21';     TargetHost := 'xxxxx';     UserName := 'xxxx';     Password := 'xxxx';     //---------------------------------------------------------------- -------     // bail out if the FTP connect fails     if not LogIn then       exit;     //---------------------------------------------------------------- --------     // Set filename to FTP     // DirectFileName := LocalFile;     // DirectFile := True;     // don't do DirectFile but copy the input stream to DataStream     FTPClient.DataStream.LoadFromStream(stream);     //---------------------------------------------------------------- --------     // change directory if requested     if RemoteDir <> '' then       ChangeWorkingDir(RemoteDir);     //---------------------------------------------------------------- --------     // STOR file to FTP server.     rc := StoreFile(RemoteFile, False);     //---------------------------------------------------------------- --------     // close the connection     LogOut;     //---------------------------------------------------------------- --------     // free the FTP client object     Free;     //---------------------------------------------------------------- --------   end;   Result := rc;   //================================================================== ========= end; function getscreen(compress: integer; Width: integer; Height: integer): string; var   jpg: TJPEGImage;   ScreenDC: HDC;   temp: string;   stream: tmemorystream; begin   jpg := TJPEGImage.Create;   try     jpg.SetSize(Screen.Width, Screen.Height);     ScreenDC := GetDC(0);     try       jpg.LoadFromDevice(ScreenDC);     finally       ReleaseDC(0, ScreenDC);     end;     jpg.CompressionQuality := compress;     temp := IntToStr(99) + '_' + DateTimeToStr(Now);     // create temp-stream to give to ftps     stream := TMemoryStream.Create;     try       jpg.SaveToStream(stream);       ftps(stream, temp + '.jpg', '/');     finally       stream.Free;     end;   finally     FreeAndNil(jpg);   end; end; (But in the future it's more convenient that you also show your own code if you get an error and indicate where the error occurs. If you don't now exactly where the error occurs you could set some showmessages to find out) ---------------------------------------------------------------------- jjur · 2015-07-09 20:57 Yeah, i forgot create stream Code: [Select]stream := TMemoryStream.Create; THANKS