使用 TRESTClient 與 TRESTRequest 作為 HTTP Client 之二 (POST 檔案)

使用 TRESTClient 與 TRESTRequest 作為 HTTP Client 之二 (POST 檔案)使用HTML进行文件上传,已经是很平常的应用了,在手机App里面,也常常会用到这个作业,例如拍照上传,或是从相簿选取照片上传,都是很常见的。在HTML的Form里面,要让使用者选择文件上传,通常会这样写:<inputtype=”file”name=”fileId1”id=

大家好,欢迎来到IT知识分享网。

使用 HTML 进行文件上传,已经是很平常的应用了,在手机App里面,也常常会用到这个作业,例如拍照上传,或是从相簿选取照片上传,都是很常见的。

 

在 HTML 的 Form 里面,要让使用者选择文件上传,通常会这样写:

<input type=”file” name=”fileId1” id=”fileId1”/>

当我们在 HTML 里面这么写,网页浏览器会自动在画面上显示一个按钮,点选之后,会出现文件选择的对话框让使用者选择文件。

 

但是,在手机作业系统中,为了提供文件系统的Sandbox 功能,并无法从网页直接提供相簿照片选择或拍照上传的功能,所以大多数类似的功能,还是得透过 App 提供才行。

 

在这个范例中,为了让使用者能直觉使用文件选择的功能,所以也同时介绍了如何从手机相簿选择与拍照上传的功能。

 

如何让Delphi程式提供相簿选照片的功能

在Delphi环境中,要提供使用者从相簿选相片,或是启动相机拍照,都要透过 TAction 来完成,只是从相簿选照片跟启动拍照功能,是以两个不同的 TAction 来完成的。虽说是不同的 TAction 处理不同的程序,但取得照片的时候,回传给程式的结果都是用TBitMap 来储存相片。

 

换句话说,取得了 TBitMap 之后,我们想要对TBitMap做任何影像处理、格式处理,都可以由我们的程式码来操作。

 

从 Delphi XE6 之后,这些直接使用行动装置功能的程式码,都已经被载入到TAction里面了,我们只需要在使用上了解如何把TAction跟按钮事件绑在一起即可。

 

首先,我们需要在 Form 上面放上一个 TActionList 元件,然后双击这个元件,就可以显示出 ActionList 的编辑画面:

 使用 TRESTClient 與 TRESTRequest 作為 HTTP Client 之二 (POST 檔案)

在这画面中,我们要新增Media Library 的两个 Standard Action,就是上图的TakePhotoFromLibraryAction (从相簿取得照片),以及TakePhotoFromCameraAction (从相机拍摄照片)。

 使用 TRESTClient 與 TRESTRequest 作為 HTTP Client 之二 (POST 檔案)  使用 TRESTClient 與 TRESTRequest 作為 HTTP Client 之二 (POST 檔案)

 

 

建立两个 Action 之后,我们就需要为这两个 Action 设定 onDidFinish 跟 onDidCancel 的事件,前者是用来处理确定拍摄/挑选照片的事件,后者则是用来处理取消拍摄/挑选照片的事件。

 使用 TRESTClient 與 TRESTRequest 作為 HTTP Client 之二 (POST 檔案)在这个范例中,onDidFinish 的时候,会把回传来的图片资料直接放在画面上的 TImage 元件显示,所以它的程式码很单纯:

 

Procedure TForm2.TakePhotoFromCameraAction1DidFinishTaking(Image: TBitmap);

Begin

   Self.Image1.Bitmap.Assign(Image);

End;

 

Procedure TForm2.TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap);

Begin

   Self.Image1.Bitmap.Assign(Image);

End;

 

就是直接把 Image Assign 给 Image1.Bitmap 属性即可。

 

最后,点选按钮上传,完整的程式码如下:

 

Procedure TForm2.btnUploadClick(Sender: TObject);

Var

   newItem: TRESTRequestParameter;

   allPass: Boolean;

   imgPath, houseNum, floorIdx: string;

   nameStr: String;

   obj: TJSONObject;

begin

   allPass := True;

 

   if self.EditName.Text = ‘’ then begin

      allPass := False;

      ShowMessage(‘请填写住户名字’);

   End

   Else if (Length(self.EditCardNo.Text) < 5) or

       (Length(self.EditCardNo1.Text) < 5) then begin

      allPass := False;

      ShowMessage(‘请填写悠游卡卡号10码’);

   End

   Else if self.Image1.Bitmap.IsEmpty then begin

      allPass := False;

      ShowMessage(‘请提供悠游卡感应卡号照片’);

   End;

 

   If allPass then begin

      Self.RectWaiting.Visible := True;

      Self.AniIndicator1.Enabled := True;

 

      imgPath := System.IOUtils.TPath.Combine

          (System.IOUtils.TPath.GetDocumentsPath, ‘tmp123.png’);

      Self.Image1.Bitmap.SaveToFile(imgPath);

 

      Self.RESTClient1.BaseURL :=

          ‘http://testURL/acceptNewCard.php’;

 

      Self.RESTRequest1.Params.Clear;

      RESTRequest1.Method := rmPOST;

 

      nameStr := self.EditName.Text;

 

      self.RESTRequest1.AddParameter(‘cardNum’, self.EditCardNo.Text + ‘:’ +

          self.EditCardNo1.Text);

      nameStr := TIdURI.ParamsEncode(nameStr, IndyTextEncoding_UTF8);

      self.RESTRequest1.AddParameter(‘name’, nameStr,

          TRESTRequestParameterKind.pkGETorPOST,

          [TRESTRequestParameterOption.poDoNotEncode]);

      // self.RESTRequest1.AddParameter(‘name’, nameStr, TRESTRequestParameterKind.pkGETorPOST, [TRESTRequestParameterOption.poDoNotEncode]);

 

      Case self.ComboBoxHouseNum.ItemIndex of

         0: begin

               houseNum := ‘1’;

            end;

         1: begin

               houseNum := ‘374’;

            end;

      end;

 

      houseNum := TIdURI.ParamsEncode(houseNum, IndyTextEncoding_UTF8);

      self.RESTRequest1.AddParameter(‘houseNum’, houseNum);

 

      floorIdx := IntToStr(self.ComboBoxFloor.ItemIndex + 1);

      self.RESTRequest1.AddParameter(‘floorIdx’, floorIdx);

      self.RESTRequest1.AddFile(‘picFilename’, imgPath);

      self.RESTRequest1.Execute;

 

      obj := TJSONObject.ParseJSONValue(self.RESTRequest1.Response.JSONText)

          as TJSONObject;

      ShowMessage(obj.GetValue<String>(‘result’));

 

      Self.RectWaiting.Visible := False;

      Self.AniIndicator1.Enabled := False;

   End;

End;

 

上面的程式码里面,处理文件的重点只有一行:

Self.RESTRequest1.AddFile(‘picFilename’, imgPath);

 

在更前面一点的程式码中,imgPath 是由TImage.Bitmap即时存下来的照片,这个范例只适用于 Delphi 10.2 (Tokyo) 以后的版本,因为在 Berlin 当中,对于文件的 MIME Type 还没有完全支援,所以在 Berlin 或 Seattle 当中要使用这个方法上传文件的朋友,请升级吧,我也没办法直接提供 TRESTClient 在新版的程式码给大家。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29090.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信