如何建立一個有趣的二維碼項目和學(xué)習(xí) Azure 函數(shù)
如果你想學(xué)習(xí)如何構(gòu)建 Azure 函數(shù),這里有一個有趣的項目。這個項目有點傻,但是很有教育意義。
我們將構(gòu)建一個二維碼生成器,它在 Azure 函數(shù)中100% 運行。互聯(lián)網(wǎng)上有成千上萬的二維碼生成器,所以這是一個愚蠢的練習(xí),但我想挑戰(zhàn) Azure 函數(shù)的極限,向你展示它們是多么的酷,并激勵你用它們創(chuàng)建很酷的東西。
如果你更喜歡看視頻,我們這里有完整的教程:
在本教程中,你將學(xué)到:
- Azure 函數(shù)是如何工作的,它們有多簡單
- 如何使用.NET 庫生成 QR 碼
- 建造這樣的東西需要多少努力
這會很有趣的,我希望你能跟著我學(xué)習(xí)。我們將在這個教程中做什么:
- 創(chuàng)建 Azure 函數(shù)
- 實現(xiàn)一個 QR 生成器
- 為它建立一個粗糙的前沿陣地
- 使用 Azure 函數(shù)核心工具將其部署到 Azure
在本教程的最后,您將擁有一個功能性的二維碼生成器,它可能會激發(fā)您使用 Azure 函數(shù)構(gòu)建更酷的東西。它們結(jié)構(gòu)緊湊、簡單、易于構(gòu)建。
您可以在這里找到該項目的完整源代碼。
什么是 Azure 函數(shù)?
Azure 函數(shù)是運行在 Azure 中的無服務(wù)器應(yīng)用程序。它們是可以在沒有服務(wù)器或復(fù)雜實例的情況下執(zhí)行的小塊代碼。大多數(shù) Azure 函數(shù)都是“微服務(wù)”,它們完成一個小任務(wù),并且做得很好。
Azure 函數(shù)還可以響應(yīng) HTTP 觸發(fā)器,作為一種“迷你 API”它們像 Web API 一樣響應(yīng) HTTP 請求,但是使用函數(shù)的設(shè)置要少得多。
我開始聽起來像一個廣告,但它是令人敬畏的。幾年前,這個項目要求您在某個 IIS 服務(wù)器上設(shè)置服務(wù)器或 ASP.NET Web API。現(xiàn)在我們只需要幾行代碼就可以做到這一點,并將其推送到云端。Azure 函數(shù)允許你專注于構(gòu)建很酷的東西,而不是所有的設(shè)置。
規(guī)定
以下是本教程所需的內(nèi)容。我將在 windows11中構(gòu)建它,但我們不使用 VisualStudio。我將使用這個 dotnet 驅(qū)動程序,所以您可以在 mac 或 OSX 上復(fù)制它,如果您愿意的話。你必須在你的機器上安裝這個(免費的)軟件。
你需要:
- 微軟 Azure Account 帳戶
- .NET 6
- Azure Functions Core Tools
- Azure CLI Tools Azure CLI
- Visual Studio Code VisualStudio
我們開始吧!
創(chuàng)建新項目
我們將使用 Azure CLI 為我們創(chuàng)建一個新的 Azure 函數(shù),我們將使用 dotnet 驅(qū)動程序來安裝軟件。
VisualStudio 可以為我們實現(xiàn)自動化,但是這樣做可以更好地了解所涉及的步驟,并且可以在許多平臺上完成。
首先,我們將初始化一個新函數(shù)。我們將使用 func 命令創(chuàng)建一個名為 QRCodeGen 的新項目。我們將工作者運行時指定為“ dotnet”來選擇 C # 作為所使用的語言。
在項目或存儲庫文件夾中運行此命令:
Shell
func init QRCodeGen --worker-runtime dotnet
如果你看一下文件夾,里面沒什么東西:
我們?nèi)匀恍枰陧椖恐袆?chuàng)建一個 Azure 函數(shù)。Azure 函數(shù)有一組模板,這取決于您正在開發(fā)的應(yīng)用程序的類型。我們希望創(chuàng)建一個 HTTP 觸發(fā)器,一個響應(yīng) HTTP 請求的函數(shù)。
Shell
func new --template "Http Trigger" --name QRCodeGen --authlevel anonymous
如果您正在使用 VisualStudio 代碼,您可能會看到以下消息:
選擇 yes 來安裝擴展。
現(xiàn)在您將看到 func 為您創(chuàng)建的一個示例函數(shù):
如果您想嘗試,可以在本地運行它
Shell
func start
然后您將看到函數(shù)啟動,控制臺將向您提供一些關(guān)于如何使用應(yīng)用程序的指導(dǎo):
正如我們所看到的,我們可以向
http://localhost:7071/api/qrcodegen 發(fā)送 GET 或 POST。讓我們在瀏覽器中加載它,看看一個簡單的 GET 返回什么:
我們有一條信息顯示:
This HTTP triggered function was executed successfully. Pass a name in the query string or in the request body for a personalized response.
好的,讓我們深入研究一下代碼,看看這條信息是什么意思。
C#
string responseMessage = string.IsNullOrEmpty(name)br ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."br : $"Hello, {name}. This HTTP triggered function executed successfully.";
正如您在上面的代碼中看到的,它正在檢查名稱中的值。如果該變量為空或 null,它將顯示我們剛才看到的消息。
但我們?nèi)绾翁畛溥@個值呢?幾行之后,我們在查詢中看到一個可以使用的參數(shù):
C#
string name = req.Query["name"];
如果它被填充,它將顯示一條包含名稱的消息。我們需要向它發(fā)送一個 URL,名稱作為一個參數(shù),如下所示:
http://localhost:7071/api/QRCodeGen?name=Jeremy
讓我們試試這個:
這是我的留言。現(xiàn)在我們知道函數(shù)正在按預(yù)期工作。我們加載一個 URL,獲取參數(shù)并修改輸出。
為了簡單起見,我們將把這個模型用于我們的二維碼生成器。我們將建立監(jiān)聽請求的 URL,并在 GET 命令中傳遞該值,然后返回一個二維碼。讓我們從生成二維碼開始。
安裝 QRCode 生成工具
將文本轉(zhuǎn)換成二維碼是相對復(fù)雜的。幸運的是,你在吸毒。NET.你不必手工制造發(fā)電機。這個問題很久以前就解決了。我們將使用庫生成一個。我們的 PNG 二維碼。我們只需要圍繞它編寫一些代碼,并構(gòu)建一個工具來解決我們的問題。
首先,讓我們從 Manuel BL 安裝 QRCode Generator 包。我們會使用網(wǎng)絡(luò)驅(qū)動程序。我將在撰寫本文時指定最新版本。
Shell
dotnet add package Net.Codecrete.QrCodeGenerator --version 2.0.1
QRCode 生成器工作得很好,但只能生成。Svgs.因為我們想要一個。PNG (位圖)格式,并希望它在多種環(huán)境下工作,我們需要安裝 SkiaSharp 軟件包:
Shell
dotnet add package SkiaSharp
SkiaSharp 包含了生成位圖的功能,但是你必須下載并將這個文件添加到你的項目中:
https://github.com/manuelbl/QrCodeGenerator/blob/master/Demo-SkiaSharp/QrCodeBitmapExtensions.cs
在項目文件夾中創(chuàng)建一個名為 qrcodebitmapextensions.cs 的文件,并將該文件的內(nèi)容復(fù)制到該文件中。這將允許您使用位圖,特別是。PNG 文件。
現(xiàn)在我們有了 QR 碼生成工具,讓它在函數(shù)中工作吧。
創(chuàng)建 QR 碼生成器函數(shù)
如果你打開 QRCodeGen.cs,你會看到為我們生成的 Azure 函數(shù)(一個方法) ,它看起來像這樣:
C#
[FunctionName("QRCodeGen")]br public static async Task<IActionResult> Run(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,br ILogger log)br {br log.LogInformation("C# HTTP trigger function processed a request.");brbr string name = req.Query["name"];brbr string requestBody = await new StreamReader(req.Body).ReadToEndAsync();br dynamic data = JsonConvert.DeserializeObject(requestBody);br name = name ?? data?.name;brbr string responseMessage = string.IsNullOrEmpty(name)br ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."br : $"Hello, {name}. This HTTP triggered function executed successfully.";brbr return new OkObjectResult(responseMessage);br }
讓我們刪除這個方法:
C#
namespace QRCodeGenbr{br public static class QRCodeGenbr {brbr }br}
接下來,讓我們添加一個生成 QR 碼的新方法。
首先,添加名稱裝飾器。這將為方法提供一個名稱并更改 URL 以訪問它。
C# C #
[FunctionName("GenerateQRCode")]
現(xiàn)在,當我們運行我們的應(yīng)用程序,網(wǎng)址將是:
http://localhost:7071/api/GenerateQRCode
這將是我們調(diào)用來生成二維碼的 URL,我們將從 JAVAScript 調(diào)用它。
接下來,創(chuàng)建方法:
C#
public static async Task<IActionResult> Generate(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)br {brbr }
我們正在創(chuàng)建一個名為 Generate 的方法,我們傳入一些參數(shù)來告訴應(yīng)用程序我們需要一個 HttpTrigger:
[HttpTrigger
在這個觸發(fā)器中,我們傳遞了一些參數(shù)。
我們希望將授權(quán)設(shè)置為匿名,以便任何人都可以訪問它:
AuthorizationLevel.Anonymous
我們只想接受對此 URL 的 GET 請求,因此下面的參數(shù)指定:
"get",
然后我們將路線設(shè)置為空。如果我們想要一個不同的 URL 或特定的路由,我們可以在這里指定它。為了簡單起見,我們就讓它保持原樣:
Route = null)]
接下來,我們將傳入一個 HttpRequest 對象。這將包含來自傳入請求的數(shù)據(jù),以便我們可以從中獲取參數(shù)。當一個 GET 請求被發(fā)送到我們的函數(shù)中時,我們可以提取頭、參數(shù)等信息。
HttpRequest req
最后,我們將傳入一個日志記錄器,以便能夠記錄消息。
ILogger log
很好,現(xiàn)在我們已經(jīng)構(gòu)建了方法,讓我們填寫它。
從查詢字符串收集信息
用戶必須發(fā)送他們想要轉(zhuǎn)換成二維碼的文本。通常是個網(wǎng)址。我們很早就決定讓事情變得簡單。我們將從發(fā)送到 API 的查詢字符串中收集這些信息。
還記得我們傳遞給方法的 HttpRequest 嗎?我們可以從中得到 Query 參數(shù)。我們可以建立一個字符串變量,然后從查詢字符串中獲取參數(shù):
C#
string qrtext = req.Query["qrtext"];
添加以下消息以記錄輸出。我們想顯示發(fā)送到 qrtext 變量的內(nèi)容:
C#
log.LogInformation("Generating QR Code for {0}", qrtext);
這樣,我們就可以復(fù)查發(fā)送的內(nèi)容了。
現(xiàn)在,讓我們生成我們的二維碼。
生成二維碼到 PNG
接下來,我們需要獲取字符串,將其編碼為二維碼,然后將其導(dǎo)出為 PNG。
因此,我們將對之前安裝的 QRCode 庫進行靜態(tài)調(diào)用。我們將傳入要生成的文本和錯誤糾正值。中號就可以了。
C#
var qr = QrCode.EncodeText(qrtext, QrCode.Ecc.Medium);
這就是生成二維碼的全部過程。但它是 SVG 格式的。我們需要把它轉(zhuǎn)換成一個 PNG,這樣我們就可以顯示它。
由于我們在上面添加了位圖擴展,現(xiàn)在我們的 QR 對象有一個方法可以將 QR 代碼轉(zhuǎn)換成帶有一些參數(shù)的 PNG。
我們需要添加一個比例: 我使用了10,這似乎產(chǎn)生了一個不錯的大小。
我用1表示邊界。
然后我將前景(代碼)設(shè)置為 SKColors。黑色,背景設(shè)置為 SKColors。白色。
輸入密碼如下:
C#
var pngout = qr.ToPng(10, 1, SkiaSharp.SKColors.Black, SkiaSharp.SKColors.White);
現(xiàn)在我們有了二維碼。太簡單了!現(xiàn)在讓我們將其打包為 JSON 并發(fā)送出去!
創(chuàng)建 JSON 返回對象
我們一直在公共靜態(tài)類 GenerateQRCode 中創(chuàng)建此代碼。讓我們創(chuàng)建另一個類,它將創(chuàng)建一個簡單的對象,我們可以在調(diào)用 API 時返回這個對象。
在 GenerateQRCode 類的外部(在最后一個}之前)創(chuàng)建一個 Return nObject 類。
這個類只有一個名為 Image 的屬性。這將是一個字符串,我們將把 PNG 編碼為文本。
C#
public class ReturnObject {br public string Image { get; set; }br}
現(xiàn)在回到 GenerateQRCode 類,讓我們回到剛才的地方,我們將創(chuàng)建一個新的 Return nObject:
C#
var ourResult = new ReturnObject{};
現(xiàn)在,我們將 PNG 映像轉(zhuǎn)換為 Base64字符串,并將該字符串添加到返回對象中:
C#
ourResult.Image = Convert.ToBase64String(pngout);
放松。現(xiàn)在我們將把 POCO (普通的舊類對象)作為一個新的 JsonResult 返回,因此它將 JSON 返回給調(diào)用者:
C#
return new JsonResult(ourResult);
就是這樣。在大約七行代碼中,我們將一個字符串轉(zhuǎn)換成二維碼,然后將其發(fā)送出去.
我們來試試。
本地啟動函數(shù)
我們將啟動這個函數(shù)并讓它在本地偵聽。我們將發(fā)送一個帶有查詢的 GET 請求來測試它。
在命令行中鍵入以下內(nèi)容:
Shell
func start
啟動函數(shù)。
你應(yīng)該看看這樣的東西:
現(xiàn)在我們將向
http://localhost:7071/api/GenerateQRCode
請記住,我們在代碼中指定的參數(shù)是 qrtext,因此我將把它添加到最后:
http://localhost:7071/api/GenerateQRCode?qrtext="hello world"
我正在使用 Postman 進行此操作,因此可以看到呈現(xiàn)的 JSON:
我們所做的日志記錄表明,它呈現(xiàn)的是“ hello world”:
所以步驟很簡單:
- 發(fā)送一個 GET 到我們的 URL
- 追加要生成的文本并將其添加到 qrtext
- 接受 JSON
這是我們目前輸入的所有代碼:
C #
public static class QRCodeGenbr {br [FunctionName("GenerateQRCode")]br public static async Task<IActionResult> GenerateQRCode(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)br {br string qrtext = req.Query["qrtext"];br log.LogInformation("Generating QR Code for {0}", qrtext);brbr var qr = QrCode.EncodeText(qrtext, QrCode.Ecc.Medium);br var pngout = qr.ToPng(10, 1, SkiaSharp.SKColors.Black, SkiaSharp.SKColors.White);
這很棒,但我們還沒完。我們還需要部署它。但在此之前,讓我們構(gòu)建一個小型的、簡單的 JavaScript 前端來與這個函數(shù)交互。
建造前端
我們希望這個二維碼生成器是完全獨立的。盡管 Azure 函數(shù)并不是真正用來提供網(wǎng)頁服務(wù)的,但它是可能的。在這種情況下,我們可以設(shè)置它,這樣就不需要在其他地方托管前端。這只是一個簡單的網(wǎng)頁,所以讓我們提供它。
首先,我們將創(chuàng)建index.html。
創(chuàng)建一個名為 www 的文件夾并創(chuàng)建一個名為 index.html 的文件。
這將是一個超級簡單,粗糙的前端ーー沒有什么花哨的,只是足以完成工作。
在頂部加入以下內(nèi)容:
HTML
<!DOCTYPE html>br<html>br<body>brbr<h2>QR Code Generator</h2>
這是我們的基本標題。接下來,我們需要添加一個輸入來獲取用戶的文本。
HTML
<input id="inputbox" style="width: 250px;" ></input>br<br /><br />
這個輸入的 id 是 inputbox,因此我們可以使用 JavaScript 獲取這段文本。我在后面添加了幾個斷行符,以便將其間隔開。
接下來,我們將創(chuàng)建一個調(diào)用 JavaScript 函數(shù)的按鈕:
HTML
<button type="button" onclick="GetQRCode()">Create QR Code</button>
然后我們會有一個地方,我們將插入二維碼。請記住,這將是 Base64編碼的,因此我們可以在 GetQRCode 函數(shù)中用圖像填充這個 div。
HTML
<div id="demo"></div>
接下來,我們將放入 GetQRCode 函數(shù),它將把一個 XMLHttpRequest 返回到 Azure 函數(shù)中并檢索 JSON。然后它解析它,并用我們的映像替換“ demo”div。注意,我們添加了一個帶有頭信息的 img 標記,這樣它就創(chuàng)建了一個我們可以在瀏覽器中查看的圖像。
C#
function GetQRCode() {br var xhttp = new XMLHttpRequest();br xhttp.onreadystatechange = function () {br if (this.readyState == 4 && this.status == 200) {br var ourJSON = JSON.parse(this.responseText);br document.getElementById("demo").innerHTML = "<img src="data:image/png;base64, " + ourJSON.image + "">";br }br };br input = document.getElementById('inputbox').value xhttp.open("GET", "/api/GenerateQRCode?qrtext=" + input, true);br xhttp.send();br} <br/script>
很好! 現(xiàn)在我們有了一個索引頁面,它將為我們的 QRCode Generator 繪制一個小 UI。
我知道我們可以添加錯誤糾正/處理或使用一個庫,但我想讓它盡可能簡單。
接下來,我們需要使用 Azure 函數(shù)來完成這個任務(wù)。
提供index.html
Azure 函數(shù)并不打算成為 Web 服務(wù)器。事實上,Azure 靜態(tài) Web 應(yīng)用程序做得更好,但是我們盡量保持它的簡單性。一個 Azure 函數(shù)來完成這個任務(wù)。
我們可以推出 index.html 文件,這樣它將由瀏覽器提供。這為我們的應(yīng)用程序提供了一個小的界面,我們可以稍后回過頭來構(gòu)建一個完整的 Web 應(yīng)用程序,利用這個功能,或者將其添加到一個微服務(wù)包中(如果愿意的話)。
再次打開 generateqrcode.cs ,在類的頂部(在[ FunctionName (“ Form”)]上)添加另一個函數(shù)。
我們希望這個函數(shù)這次返回一個 HttpResponseMessage。我們?nèi)詫⑹褂媚涿矸蒡炞C將其設(shè)置為 HttpTrigger,并傳入與前面相同的值。
但是這一次,我們需要傳遞 ExectionContext 上下文。這為我們提供了執(zhí)行上下文,這樣我們就可以在本地文件系統(tǒng)中定位文件,稍后我將解釋其中的原因。
另一個是這將返回 HttpResponseMessage 而不是 IActionResult。
C# C #
[FunctionName("Form")] brpublic static HttpResponseMessage Form([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] br HttpRequest req, ILogger log, ExecutionContext context){
接下來,我們將打開放在 www 文件夾中的 index.html 文件,并將其全部作為文本讀入。這就是執(zhí)行上下文的來源。
我們希望打開運行應(yīng)用程序的文件系統(tǒng)的 www 文件夾中的 index.html 文件。我們用這行代碼來實現(xiàn):
C#
string indexPage = File.ReadAllText(context.FunctionAppDirectory + "/www/index.html");
然后,我們將創(chuàng)建一個狀態(tài)代碼為 OK (200)的新 HttpResponseMessage:
C#
var result = new HttpResponseMessage(HttpStatusCode.OK);
現(xiàn)在我們需要添加一些標題,并用我們從索引文件中讀取的文本填充“內(nèi)容”:
C#
result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");brresult.Content = new ByteArrayContent(System.Text.Encoding.UTF8.GetBytes(indexPage));
現(xiàn)在我們有了一個帶有 text/html 頭的200 OK 消息,并且我們已經(jīng)將來自 index.html 的所有文本添加到了頭的內(nèi)容部分。
很俗氣,但很管用。
然后我們就把它還回去:
C#
return result;
所以整個函數(shù)看起來是這樣的:
C#
[FunctionName("Form")]brpublic static HttpResponseMessage Form(br [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,br ILogger log, ExecutionContext context)br{brbr string indexPage = File.ReadAllText(context.FunctionAppDirectory + "/www/index.html");brbr var result = new HttpResponseMessage(HttpStatusCode.OK);brbr result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
因為我們要引入這個需要包含在構(gòu)建中的外部文件(index.html) ,所以需要將它添加到我們的。Csproj 文件。在 ItemGroup 中,添加以下代碼:
HTML
<None Update="wwwindex.html">br <CopyToOutputDirectory>Always</CopyToOutputDirectory>
我在其他文件發(fā)布設(shè)置中添加了我的:
保存它,讓我們再次在本地運行 Azure 函數(shù):
Shell
func start
讓我們看看它是如何工作的。
測試我們的前端
現(xiàn)在我已經(jīng)在本地啟動并運行了我的函數(shù),所以我可以打開一個網(wǎng)頁瀏覽器:
http://localhost:7071/api/Form
這就是它所有的榮耀:
我會輸入一個網(wǎng)址,
這是我的二維碼,臨時生成的,太棒了! !
把它部署到 Azure 上。
部署我們的應(yīng)用程序
所以我現(xiàn)在稱之為“應(yīng)用程序”,因為它就是。我們已經(jīng)超越了一個簡單函數(shù)的預(yù)期功能,只是為了展示 Azure 函數(shù)的強大。我們來部署一下,看看它是如何工作的。
用 Azure CLI 輸入
Shell
az login
你會通過瀏覽器登錄到 Azure。
在你的 Azure 控制臺中,創(chuàng)建一個新的 Azure 函數(shù)應(yīng)用程序,你可以給它取任何你喜歡的名字。
選擇發(fā)布為代碼,并使用下面的運行時堆棧。
我會選擇 Windows 和消費(無服務(wù)器)模式:
我將創(chuàng)建一個新的存儲帳戶,然后按“查看并創(chuàng)建”
把你的細節(jié)記下來:
現(xiàn)在我們需要用 Azure CLI 發(fā)布。我們將通過使用 func 命令并指定我們想要發(fā)布一個蔚藍色的 function 應(yīng)用程序的名稱來做到這一點,我們將使用“-nozip”來告訴命令我們不是在部署應(yīng)用程序的 zip,而是源代碼。
Shell
func azure functionapp publish qrcodegen --nozip
你應(yīng)該看看這樣的東西,當它完成的時候。
你將需要登錄到你的 Azure 門戶,加載功能應(yīng)用程序并選擇“配置”。
然后找到 WEBSITE _ RUN _ FROM _ PACKAGE 并將值設(shè)置為0。這將允許我們的函數(shù)在已發(fā)布的文件中運行。
我們來看看!
在 Azure 上運行應(yīng)用程序
部署之后,您應(yīng)該會看到如下屏幕:
“表單”URL 將顯示我們函數(shù)的用戶界面:
你可以在你的網(wǎng)站,并創(chuàng)建一個二維碼從它!
我們自己的二維碼生成器100% 運行 Azure 函數(shù)。
結(jié)論
如果你一直在跟進,謝謝你堅持下來!現(xiàn)在您有了一個很酷的項目,并且對 Azure 函數(shù)有了更好的了解。此項目的完整源代碼位于此處。
提供網(wǎng)站服務(wù)并不是 Azure 功能的設(shè)計目的,但我希望這是一個完整的解決方案,以支持 Azure 功能。沒有服務(wù)器,沒有數(shù)據(jù)庫,并且您不需要跟蹤多個服務(wù)。
我們學(xué)習(xí)了 Azure 函數(shù)的工作原理以及它們的簡單性。我們在這里寫的代碼不多!我們學(xué)會了如何生成二維碼。NET 庫,構(gòu)建一個迷你應(yīng)用程序并將其部署到云中。我想盡可能簡單地介紹一下。如果您正在構(gòu)建一個“真正的”應(yīng)用程序,以下是我的建議:
- 在 Azure 靜態(tài) Web 應(yīng)用程序或類似服務(wù)上托管前端
- 檢查輸入時出錯
- 優(yōu)雅的錯誤處理和日志記錄
- 將圖像推入存儲器以便以后檢索
- 設(shè)計 API,以便其他類型的應(yīng)用程序也可以使用它






