2017-02-10 19 views
0

У меня есть 2 приложения Позвоним на сервер и клиент.Как получить изображения с сервера с помощью приложения Tethering

Я использую Delphi-xe8. Приложение -> Многоуровневое приложение

В обеих сторонах, используя: привязку приложений [tManager, tAProfile], базу данных SQLite.

В базе данных SQLite SQL у меня есть 6 изображений. Я хотел бы посмотреть, что изображения на стороне клиента.

На стороне клиента У меня 6 [TImage].

Когда я нажимаю кнопку «Получить список изображений», я получаю 6 изображений с одинаковым видом.

Я хотел бы 6 изображений смотреть по-разному .-> [Получить Из базы данных сервера] Кнопка

Client Side

Client "Получить список изображений" Код:

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, как это сделать в своем ответе на его q вчера: http: //stackoverflow.com/questions/42140246/delphi-how-to-get-all-images-from-server -database-на-используя приложение-привязывать/42144117 # 42144117. Он, кажется, не видит, как получить данные из его Sqlite db в ClientDataSet, о чем я расскажу в одно мгновение. – MartynA

ответ

2

Обновление: Я собираю с вашего последнего комментария, который вы хотите отправить ваши изображения один за другим.

Проблема в том, что 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.

+0

Тип набора данных: rQuery: TFDQuery –

+0

@AlexKirov: Я добавил полный клиент FireDAC Server + на мой ответ. – MartynA

+0

Это не то, что я хочу. Мне нужно разделить с сервера MS1 и от клиента AResource.Value.AsStream) –

 Смежные вопросы

  • Нет связанных вопросов^_^