2017-02-10 12 views
0

私は2つのアプリケーションを持っています。サーバーとクライアントを呼び出しましょう。アプリケーションテザリングを使用してサーバーからイメージを取得する方法

私はDelphi-xe8を使用しています。 App - >マルチデバイスアプリケーション

両側使用:Appテザリング[tManager、tAProfile]、SQLiteデータベース。

サーバSQLiteデータベースでは、私は6つの画像を持っています。クライアント側の画像を見たいと思います。

クライアント側では6 [TImage]でした。

「イメージリストを取得」ボタンをクリックしたとき同じビューで6つのイメージを取得しています。

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

Serverが受信:

私は6個のイメージが違った.->

Client Side

クライアント "画像一覧を取得" ボタンのコードを[サーバー・データベースから取得]ビューたいですコード:

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を使用しています。 App - > Multi-Device Application –

+0

このスクリーンショットは、同じことを聞いた昨日の質問とは関係ありません。あなたのサーバーアプリケーションではどのようなデータセットタイプを使用していますか? – MartynA

+0

@TomBrunberg:私はすでにどのようにOPを示してきた彼のQ昨日の私の答えでこれを行うにします。http://stackoverflow.com/questions/42140246/delphi-how-to-get-all-images-from-server -database-by-using-app-tethering/42144117#42144117。彼が見逃しているステップは、SqliteのdbからClientDataSetにデータを取得する方法です。 – MartynA

答えて

2

アップデート:私はあなたがあなたの 画像一つずつ送りたいあなたの最も最近のコメントから集まる

問題は、DelphiデータセットのTGraphicFieldは、可変サイズのものとすることができるフォーマット の数をサポートしていることですので、あなただけのサーバーのアウトバウンド ストリームに書き込む場合は読み込み時に、クライアントが知る方法はありません1つの画像のデータが終了し、次の画像のデータが始まるストリーム。その簡単な解決策は、 サーバーが画像のサイズをストリームに書き込んでから、画像の データをストリームに書き込み、クライアントのコードを取得して画像サイズを読み取ることです。 画像のデータは次のとおりです。

TClientDataSets、 を使用していますが、ストリーム内のイメージ(およびサイズ)のみを送信するように、他のq(Delphi: How to Get All Images From Server Database by using App tethering?)に投稿した回答に戻ります。 コードはまだかなり単純で、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を使用して、サーバーとクライアントの間で画像を移動する非常に簡単な方法をq01の回答で示しました。私は、Sqlite dbからTCientDataSetにデータを取得できるようにするには、Delphiプログラミングについて十分に知っていると思っていましたが、おそらくそうではないと思いました。

以下は私の他の答えのサーバー+クライアントのコードで、代わりにTClientDataSetsのFireDACコンポーネントを使用するようになって。ここでもサーバーデータセットのSaveToStreamメソッドを使用して、サーバーからのストリームにデータを保存し、クライアント側にはLoadFromStreamを保存します。クライアントアプリケーションのコードの2つだけの行があること

は注意してください。

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; 

、クライアント側では、何らかの理由であなたがしたい場合にコピー画像(ではなく、他のサーバーのデータ)別のデータセットを使用する場合は、qのコードと同様に、行単位のコピーで行うことができます。

+0

データセットの種類:rQuery:TFDQuery –

+0

@AlexKirovに:私は私に完全なFireDACサーバー+クライアントを追加しました回答。 – MartynA

+0

これは私が望むものではありません。私は、サーバーMS1からとクライアントAResource.Value.AsStream) –

関連する問題