Обновление: Я собираю с вашего последнего комментария, который вы хотите отправить ваши изображения один за другим.
Проблема в том, что TGraphicField набора данных Delphi поддерживает множество форматов , которые могут быть различного размера, так что если вы просто записать их в исходящий поток сервера, нет никакого способа для клиента, чтобы знать, когда чтение поток, где заканчиваются данные одного изображения, и начинается следующий. Простое решение состоит в том, чтобы иметь сервер записывает размер изображения в поток, прежде чем он записывает данные изображения в поток и получает код клиента для считывания размера изображения, чтобы он знал, сколько из Ниже приведены данные изображения.
Я вернусь к ответу, который я отправил на ваш другой 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;
Client
// 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 db в TCientDataSet, но, возможно, нет.
Ниже приведен код для сервера + клиент моего другого ответа, адаптированный для использования компонентов FireDAC вместо TClientDataSets. Опять же, он использует метод SaveToStream
сервера dataset для сохранения своих данных в потоке с сервера и 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.
Я использую Delphi-xe8. Приложение -> Многоуровневое приложение –
Скриншоты не имеют значения для этого и вашего вопроса вчера, который задал одно и то же. Какой тип набора данных вы используете в своем серверном приложении? – MartynA
@TomBrunberg: Я уже показал OP, как это сделать в своем ответе на его q вчера: http: //stackoverflow.com/questions/42140246/delphi-how-to-get-all-images-from-server -database-на-используя приложение-привязывать/42144117 # 42144117. Он, кажется, не видит, как получить данные из его Sqlite db в ClientDataSet, о чем я расскажу в одно мгновение. – MartynA