アップデート:私はあなたがあなたの 画像一つずつ送りたいあなたの最も最近のコメントから集まる。
問題は、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のコードと同様に、行単位のコピーで行うことができます。
私はDelphi-xe8を使用しています。 App - > Multi-Device Application –
このスクリーンショットは、同じことを聞いた昨日の質問とは関係ありません。あなたのサーバーアプリケーションではどのようなデータセットタイプを使用していますか? – MartynA
@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