2017-02-10 45 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) –

相关问题