How to Get Images From Server using App Tethering

前提是你 提交于 2019-11-30 09:54:17

问题


I've 2 Apps Let's call Server And Client.

I'm using Delphi-xe8. App ->Multi-Device Application

In Both Side using: App tethering[tManager,tAProfile], SQLite Database.

In Server SQLite Database I've 6 images. I would like to View that images In Client Side.

In Client Side I've 6 [TImage].

When I Click Button 'Get Image List' I'm getting 6 images with the same view.

I would like 6 images view differently.->[Get From Server Database]

Client "Get Image List" button Code:

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

Server Received Code:

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;

Client Received Code:

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;

回答1:


Update: I gather from your most recent comment that you want to send your images one-by-one.

A problem is that a Delphi dataset's TGraphicField supports a number of formats which may be of variable size, so if you just write them to the server's outbound stream, there is no way for the client to know, when reading the stream, where the data of one image ends and the next one begins. A simple solution to that is to have the server write the size of the image to the stream before it writes the image's data to the stream, and get the client's code to read the image size so that it knows how much of what follows is the image's data.

I'm going back to the answer I posted to your other q (Delphi: How to Get All Images From Server Database by using App tethering?), which uses TClientDataSets, but adapting it so that it sends only the images (and their sizes) in the stream. The code is still quite simple and should be no different in principle than using FireDAC datasets and a Sqlite data table:

Server

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;

Original answer follows

I have already shown you a very simple way to move images between server and client app using TClientDataSets in my answer to your q Delphi: How to Get All Images From Server Database by using App tethering?. I assumed you knew enough about Delphi programming to be able to get the data from your Sqlite db into a TCientDataSet but perhaps not.

Below is the code for the server + client of my other answer, adapted to use FireDAC components instead of TClientDataSets. Again, it uses the server dataset's SaveToStream method to save its data to the stream from the server and LoadFromStream on the client side.

Notice that there are only two lines of code in the client app.

FDApp1 code:

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 code:

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;

Of course, on the client side, if for some reason you want the images (but not the other server data) copied into another dataset, you can do that by a row-by-row copy, similar to the code in your qs.



来源:https://stackoverflow.com/questions/42153215/how-to-get-images-from-server-using-app-tethering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!