使用 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 的编辑画面:

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

 

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

在这个范例中,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://www.cnblogs.com/dennieschang/p/9203559.html

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

  1. Linux 使用者身份與群組記錄的檔案

    在我們Linux系統當中,預設的情況下,所有的系統上的帳號與一般身份使用者,還有那個root的相關資訊, 都是記錄在/etc/passwd這個檔案內的.至於個人的密碼則是記錄在/etc/shadow這 ...

  2. 圖像及編程常用網址,作為收藏 Very Good

    Graphics:News,Forum,Developer Resource The Guru of 3D demonews Real Soon Now Linux Games Gamasutra - ...

  3. BNN领域开山之作——不得错过的训练二值化神经网络的方法

    作者| cocoon 编辑| 3D视觉开发者社区 文章目录 导读 概述 方法 确定二值化以及随机二值化 梯度计算以及累加 离散化梯度传播 乘法运算优化 基于位移(shift)的BN 基于位移的AdaM ...

  4. ilm 和dlm差异_NetPro 耐特普羅資訊:技術應用 / 漫談ILM與DLM-3 由DLM著手落實ILM的精神...

    漫談ILM與DLM-3 由DLM著手落實ILM的精神 "企業資訊"是個不夠具體的概念,無法聚焦.但IT仍可引用ILM的觀念於具體的應用系統資料,將其一一落實,此即資料生命週期管理 ...

  5. batocera_Batocera新手上路手冊(二):執行遊戲與基本操作說明

    ADVERTISEMENT 由於Batocera已經整合了萬能模擬器RetroArch以及必需的基本設定,可以省下一一安裝各種模擬器的功夫,使用起來相當便利,完成安裝後只需將遊戲檔案傳輸至隨身碟,就可 ...

  6. python 抓包 scapy udp,python+scapy 抓包與解析

    最近一直在使用做流量分析,今天把 scapy 部分做一個總結. python 的 scapy 庫可以方便的抓包與解析包,無奈資料很少,官方例子有限,大神博客很少提及, 經過一番嘗試后,總結以下幾點用法 ...

  7. Vue CLI 環境設定與打包

    Vue CLI (Vue.js Command-Line Interface) Vue CLI 是由 Vue.js 核心團隊所開發,用來提供開發者快速建置 Vue.js 專案並整合相關工具鍊的一套指令 ...

  8. 鸟哥的Linux私房菜(服务器)- 架站文件習題解答篇

    架站文件習題解答篇 最近更新日期:2003/09/20 在我們的 Linux 架站文件當中,每個章節或多或少都有些課後練習給大家複習一下!呵呵!那麼各個章節的解答會在這裡提供喔! PART I .架站 ...

  9. 鸟哥的Linux私房菜(基础篇)- 一些基础的Linux 问题

    一些基礎的Linux問題 最近更新日期:2005/05/23 一些基礎的 Linux 問題與討論: 注意:如果您有更好的試題,或者是有相關的資料要提供給VBird 的話,我也會盡快的將他寫到網頁中的! ...

最新文章

  1. python实现ocr识别文字
  2. JavaScript实现截留雨水问题的动态编程方法算法(附完整源码)
  3. (转)windows下安装python及第三方库numpy、scipy、matplotlib终极版
  4. 万丰科技机器人排名_2020年全国机器人企业数量大排名(省份榜|9月)
  5. 【Java线程】复盘线程池使用及思考
  6. 广东省的盆友们,这波退税及时雨你赶上了吗?
  7. SAP自学指南:案例公司的需求分析
  8. kubernetes视频教程笔记 (11)-pod容器生命周期、Init容器
  9. 智能水电表远程管理系统
  10. 使用WinDbg分析Dump文件(蓝屏示例)
  11. feiyanghaotian(飞扬浩天)的csdn博客
  12. 解决regedit taskmgr不能启动
  13. C语言入门——初识C语言
  14. 魅蓝note2手机计算机打开教程,魅族 魅蓝note2 开启USB调试模式
  15. 星起航:抖音小店体验分低怎么办,如何提高店铺体验评分?
  16. 教你一招:Win10切换输入法与Win7一样(Ctrl + 空格)
  17. 限制_blank属性只打开一个新页签
  18. 如何用手机扫二维码盘点海量固定资产?
  19. 持续使用KimJongRAT和PCRat发动攻击:BabyShark恶意软件分析
  20. 校招失败后,在小公司熬了 2 年终于进了华为,竭尽全力....

热门文章

  1. 如何用淘宝助理上传宝贝装修模板
  2. 正则表达式符号解释1
  3. css特性:空白外边距互相叠加
  4. Spring Bean装配(上)
  5. Centos6 使用yum快速搭建LAMP环境
  6. tomcat通过一个端口号实现多域名访问
  7. 【转载】java中Date与String的相互转化
  8. 安装出现 PHP Extension curl must be loaded 错误(magento)
  9. 用JS判断不同分辨率调用不同的CSS样式文件
  10. HTML-列表、表格、表单