2017-02-10 81 views
0

我有2個應用程序讓我們稱之爲服務器和客戶端。如何使用App Tethering從服務器獲取圖像

我正在使用Delphi-xe8。應用程序 - >多設備應用程序

在兩面使用:應用程序綁定[tManager,tAProfile],SQLite數據庫。

在服務器SQLite數據庫我有6個圖像。我想在客戶端查看該圖像。

在客戶端我有6 [TImage]。

當我點擊按鈕'獲取圖像列表'我得到6個相同的看法。

我想6個圖像來觀看不同 - > [從服務器獲取數據庫]

Client Side

客戶 「獲取圖像列表」 按鈕代碼:

procedure TForm1.GetImgLstClick(Sender: TObject); 
begin 
    tAProfile.SendString(tManager.RemoteProfiles.First,'GetImages',''); 
end; 

服務器接收代碼:

procedure TForm2.tAProfileResourceReceived(const Sender: TObject; 
    const AResource: TRemoteResource); 
    var 
    MS1:TMemorystream; 
begin 

    if AResource.Hint='GetImages' then 
     begin 
     MS1:=TMemorystream.Create; 

     rQuery.Close; 
     rQuery.SQL.Clear; 
     rQuery.SQL.Add('select image from users'); 
     rQuery.Open; 
     while not rQuery.Eof do 
      begin 
      tblobField(rQuery.FieldByName('image')).SaveToStream(MS1); 
      Image1.Bitmap:=nil; 
      rQuery.Next; 
      end; 
     tAProfile.SendStream(tManager.RemoteProfiles.First,'SendImages',MS1); 
     end; 
end; 

客戶端收到代碼:

procedure TForm1.tAProfileResourceReceived(const Sender: TObject; 
    const AResource: TRemoteResource); 
var 
    MS:TMemoryStream; 
begin 
if AResource.Hint='SendImages' then 
    begin 
     Image1.Bitmap.LoadFromStream(AResource.Value.AsStream); 
     Image2.Bitmap.LoadFromStream(AResource.Value.AsStream); 
     Image3.Bitmap.LoadFromStream(AResource.Value.AsStream); 
     Image4.Bitmap.LoadFromStream(AResource.Value.AsStream); 
     Image5.Bitmap.LoadFromStream(AResource.Value.AsStream); 
     Image6.Bitmap.LoadFromStream(AResource.Value.AsStream); 
    end; 
end; 
+0

我正在使用Delphi-xe8。應用程序 - >多設備應用程序 –

+0

截圖與這個和你昨天的問題無關,它們提出了同樣的問題。您在服務器應用程序中使用了哪種數據集類型? – MartynA

+0

@TomBrunberg:我已經在昨天的回答中向他展示了OP如何做到這一點:http://stackoverflow.com/questions/42140246/delphi-how-to-get-all-images-from-server -database逐使用-APP-栓系/ 42144117#42144117。他似乎缺少的一步是如何將他的Sqlite數據庫中的數據導入到ClientDataSet中,我將稍後解釋。 – MartynA

回答

2

更新:我從你最近要送你 圖像一個接一個評論集。

的一個問題是一個Delphi數據集的TGraphicField支持多種格式 這可能是大小可變的,所以如果你只是把它們寫入到服務器的出站 流,有沒有辦法讓客戶知道,閱讀時流,其中一個圖像的數據結束並且下一個圖像開始。一個簡單的解決方案是,在將圖像的 數據寫入流之前,服務器將圖像的大小寫入流,然後獲取客戶端的代碼以讀取圖像大小,以便 知道圖像的大小以下是圖像的數據。

我回到我發佈到您的其他q(Delphi: How to Get All Images From Server Database by using App tethering?)的答案,該答案使用TClientDataSets, ,但對其進行了調整,以便僅發送流中的圖像(及其大小)。該 代碼仍然是相當簡單的,應該在原則上比使用FireDAC數據集和一個SQLite數據表中沒有不同:

服務器

procedure TApp1Form.SendImageStream; 
var 
    StreamToSend, 
    ImageStream : TMemoryStream; 
    StreamedImageSize : Integer; 
begin 
    StreamToSend := TMemoryStream.Create; 
    ImageStream := TMemoryStream.Create; 
    try 
    CDS1.DisableControls; 
    CDS1.First; 
    while not CDS1.Eof do begin 
     ImageStream.Clear; 
     CDS1Graphic.SaveToStream(ImageStream); 
     ImageStream.Position := 0; 
     StreamedImageSize := ImageStream.Size; 
     StreamToSend.Write(StreamedImageSize, SizeOf(Integer)); 
     StreamToSend.CopyFrom(ImageStream, StreamedImageSize); 
     CDS1.Next; 
    end; 
    StreamToSend.Position := 0; 
    TetheringAppProfile1.Resources.FindByName('BioLife').Value := StreamToSend; 
    finally 
    CDS1.EnableControls; 
    ImageStream.Free; 
    end; 
end; 

客戶

// Note: In the client, CDS1 has only two fields, one named ID which is an 
// ftAutoInc field, and Graphic, which is a TGraphicField 

procedure TApp2Form.TetheringAppProfile1Resources0ResourceReceived(const Sender: 
    TObject; const AResource: TRemoteResource); 
var 
    ReceivedStream : TStream; 
    ImageStream : TMemoryStream; 
    ImageSize : Integer; 
begin 
    AResource.Value.AsStream.Position := 0; 

    ReceivedStream := AResource.Value.AsStream; 
    ImageStream := TMemoryStream.Create; 
    try 
    if CDS1.Active then 
     CDS1.EmptyDataSet // discard existing data 
    else 
     CDS1.CreateDataSet; 
    CDS1.DisableControls; 
    while ReceivedStream.Position < ReceivedStream.Size - 1 do begin 
     ImageStream.Clear; 
     ReceivedStream.ReadBuffer(ImageSize, SizeOf(Integer)); 
     ImageStream.CopyFrom(ReceivedStream, ImageSize); 
     CDS1.Insert; 
     TGraphicField(CDS1.FieldByName('Graphic')).LoadFromStream(ImageStream); 
     CDS1.Post; 
    end; 
    CDS1.First; 
    finally 
    ImageStream.Free; 
    CDS1.EnableControls; 
    end; 
end; 

原來的答覆如下

我已經向您展示了一種在服務器和客戶端應用之間使用TClientDataSets在我的答案中移動圖像的簡單方法q Delphi: How to Get All Images From Server Database by using App tethering?。我假設你對Delphi編程足夠了解,以便能夠將Sqlite數據庫中的數據轉換爲TCientDataSet,但可能不會。

下面是我的其他答案的服務器+客戶端的代碼,適用於使用FireDAC組件而不是TClientDataSets。同樣,它使用服務器數據集的SaveToStream方法將其數據保存到來自服務器的流中,並在客戶端側保存爲LoadFromStream

請注意,客戶端應用中只有兩行代碼。

FDApp1代碼:

type 
    TApp1Form = class(TForm) 
    TetheringManager1: TTetheringManager; 
    TetheringAppProfile1: TTetheringAppProfile; 
    DBImage1: TDBImage; 
    btnConnect: TButton; 
    Label1: TLabel; 
    DataSource1: TDataSource; 
    DBGrid1: TDBGrid; 
    DBNavigator1: TDBNavigator; 
    btnSendStream: TButton; 
    FDConnection1: TFDConnection; 
    FDQuery1: TFDQuery; 
    FDGUIxWaitCursor1: TFDGUIxWaitCursor; 
    FDStanStorageBinLink1: TFDStanStorageBinLink; 
    procedure btnConnectClick(Sender: TObject); 
    procedure btnSendStreamClick(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure TetheringManager1PairedToRemote(const Sender: TObject; const 
     AManagerInfo: TTetheringManagerInfo); 
    private 
    procedure DataSetToStream; 
    end; 

[...] 

procedure TApp1Form.btnConnectClick(Sender: TObject); 
begin 
    TetheringManager1.AutoConnect; 
end; 

procedure TApp1Form.btnSendStreamClick(Sender: TObject); 
begin 
    DataSetToStream; 
end; 

procedure TApp1Form.FormCreate(Sender: TObject); 
begin 
    Caption := Format('App1 : %s', [TetheringManager1.Identifier]); 
    FDQuery1.LoadFromFile('D:\D10\Samples\Data\BioLife.FDS'); 
end; 

procedure TApp1Form.TetheringManager1PairedToRemote(const Sender: TObject; const 
    AManagerInfo: TTetheringManagerInfo); 
begin 
    Label1.Caption := Format('Connected : %s %s', 
         [AManagerInfo.ManagerIdentifier, 
          AManagerInfo.ManagerName]); 
end; 

procedure TApp1Form.DataSetToStream; 
var 
    Stream : TMemoryStream; 
begin 
    Stream := TMemoryStream.Create; 
    FDQuery1.SaveToStream(Stream); 
    Stream.Position := 0; 
    TetheringAppProfile1.Resources.FindByName('BioLife').Value := Stream; 
end; 

FDApp2代碼:

type 
    TApp2Form = class(TForm) 
    TetheringManager1: TTetheringManager; 
    TetheringAppProfile1: TTetheringAppProfile; 
    DataSource1: TDataSource; 
    DBGrid1: TDBGrid; 
    DBNavigator1: TDBNavigator; 
    DBImage1: TDBImage; 
    FDGUIxWaitCursor1: TFDGUIxWaitCursor; 
    FDMemTable1: TFDMemTable; 
    FDStanStorageBinLink1: TFDStanStorageBinLink; 
    procedure TetheringAppProfile1Resources0ResourceReceived(const Sender: TObject; 
     const AResource: TRemoteResource); 
    public 
    end; 

[...] 
procedure TApp2Form.TetheringAppProfile1Resources0ResourceReceived(const Sender: 
    TObject; const AResource: TRemoteResource); 
begin 
    AResource.Value.AsStream.Position := 0; 
    FDMemTable1.LoadFromStream(AResource.Value.AsStream); 
end; 

當然,在客戶端上,如果由於某種原因,你想複製到的圖像(而不是其他的服務器數據)另一個數據集,你可以通過逐行拷貝來實現,類似於你的qs中的代碼。

+0

數據集類型:rQuery:TFDQuery –

+0

@AlexKirov:我已經將完整的FireDAC服務器+客戶端添加到我的回答。 – MartynA

+0

這不是我想要的。我需要分離從服務器MS1和從客戶端AResource.Value.AsStream) –

相關問題