Gradio.NET 是 Gradio 在 .NET 平臺上的移植版本。Gradio 是一個開源的 Python 包,用於快速構建機器學習模型、API 或任意 Python 函式的演示或 Web 應用程式。
Gradio.NET 繼承了 Gradio 的核心理念,以.NET 開發習慣和熟悉的方式進行Web應用開發,其主要特點包括:
-
易用性:只需幾行 .NET 程式碼即可建立功能完善的使用者介面。
-
靈活性:支援多種型別的輸入和輸出,包括文字、影像、音訊等。
-
一鍵分享:輕鬆生成訪問連結,方便進行測試和使用。
-
整合支援:能夠無縫整合到主流的 .NET 框架和庫中,如 ASP.NET Core 和 Entity Framework,加速開發和部署流程。
總而言之,Gradio.NET 是一個強大的工具,極大地簡化了建立和分享介面的過程,使我們能夠專注於業務邏輯而無需擔心複雜的前端開發工作。
Gradio.NET
Gradio.NET 是一個基於 Gradio 的 .NET 實現,我們無需掌握任何前端技術(如 JavaScript、CSS 或 HTML),僅用幾行 .NET 程式碼就能快速構建機器學習模型、API 或任意函式的演示或 Web 應用程式。
透過 Gradio.NET,可以輕鬆建立美觀的互動式 Web 介面,無需前端開發經驗。
Gradio.NET 使用
1、建立專案
建立一個新的 .NET 8 WebAPI 標準專案,選擇啟用 OpenAPI 支援和使用控制器;
dotnet new webapi -n ManageCore.Api cd ManageCore.Api
2、安裝 Gradio.Net
安裝 NuGet 包 Gradio.Net.AspNetCore
這個包。
3、示例程式碼
在 Program.cs 中輸入以下示例程式碼:
App.Launch(await CreateBlocks()); async Task<Blocks> CreateBlocks() { using (var blocks = gr.Blocks()) { gr.Markdown("開始在下面鍵入,然後點選**執行** 檢視輸出結果."); Textbox input, output; using (gr.Row()) { input = gr.Textbox(placeholder: "你叫什麼名字?"); output = gr.Textbox(); } var btn = gr.Button("執行"); await btn.Click(fn: async (input) => gr.Output($"歡迎使用 Gradio.Net, {input.Data[0]}!"), inputs: new[] { input }, outputs: new[] { output }); return blocks; } }
執行結果如下圖所示:
如果想在現有專案中使用 Gradio.NET
可以使用AddGradio
和 UseGradio
擴充套件方法:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddGradio(); var app = builder.Build(); app.UseGradio(await CreateBlocks()); app.Run();
Gradio.NET 示例
1、Layout
Gradio.NET 常用的佈局方式都包括:Row/Column、Tab、Group、Accordion等。
示例程式碼
App.Launch(await CreateBlocks()); async Task<Blocks> CreateBlocks() { using (var blocks = gr.Blocks()) { gr.Markdown("# Layout Demo"); gr.Markdown("## Row/Column"); using (gr.Row()) { using (gr.Column(scale: 1)) { var text1 = gr.Textbox(); var text2 = gr.Textbox(); } using (gr.Column(scale: 4)) { var btn1 = gr.Button("Button 1"); var btn2 = gr.Button("Button 2"); } } gr.Markdown("## Tab"); using (gr.Tab("Lion")) { gr.Textbox("lion"); gr.Button("New Lion"); } using (gr.Tab("Tiger")) { gr.Textbox("tiger"); gr.Button("New Tiger"); } gr.Markdown("## Group"); using (gr.Group()) { gr.Textbox(label: "First"); gr.Textbox(label: "Last"); } gr.Markdown("## Accordion"); using (gr.Accordion("See Details")) { gr.Markdown("lorem ipsum"); } return blocks; } }
示例效果
2、Form
表單示例程式碼,具體如下:
App.Launch(await CreateBlocks()); async Task<Blocks> CreateBlocks() { using (var blocks = gr.Blocks()) { using (gr.Column()) { var text1 = gr.Textbox(); var dropdown1 = gr.Dropdown(choices: new[] { "First Choice", "Second Choice", "Third Choice" }); var checkbox1 = gr.Checkbox(); var checkboxGroup1 = gr.CheckboxGroup(choices: new[] { "First Choice", "Second Choice", "Third Choice" }); var multimodalTextbox1 = gr.MultimodalTextbox(interactive:true); var number1 = gr.Number(); var radio1 = gr.Radio(choices: ["First Choice", "Second Choice", "Third Choice"]); var slider1 = gr.Slider(); var text_Result = gr.Textbox(label:"Form Value", interactive:false); var btn = gr.Button("Run"); await btn.Click(fn: async (input) => gr.Output($@" Textbox: {Textbox.Payload(input.Data[0])} Dropdown: {string.Join(", ",Dropdown.Payload(input.Data[1]))} Checkbox: {Checkbox.Payload(input.Data[2])} CheckboxGroup: {string.Join(", ", CheckboxGroup.Payload(input.Data[3]))} MultimodalTextbox: {MultimodalTextbox.Payload(input.Data[4]).Files.FirstOrDefault()?.OrigName} Number: {Number.Payload(input.Data[5])} Radio: {string.Join(", ", Radio.Payload(input.Data[6]))} Slider: {Slider.Payload(input.Data[7])} "), inputs: new Component[] { text1, dropdown1, checkbox1, checkboxGroup1, multimodalTextbox1, number1, radio1, slider1 }, outputs: new[] { text_Result }); } return blocks; } }
示例效果
3、Media
多媒體控制元件,具體參考程式碼
App.Launch(await CreateBlocks()); async Task<Blocks> CreateBlocks() { using (var blocks = gr.Blocks()) { gr.Markdown("**Image Demo** upload a image and click button"); Gradio.Net.Image input, output; using (gr.Row()) { input = gr.Image(); output = gr.Image(); } var btn = gr.Button("Submit"); await btn.Click(fn: async (input) => gr.Output(DrawWaterMarkOnImage(Gradio.Net.Image.Payload(input.Data[0]))), inputs: new[] { input }, outputs: new[] { output }); return blocks; } } static string DrawWaterMarkOnImage(string inputImageFilePath) { using (var img = SixLabors.ImageSharp.Image.Load(inputImageFilePath)) { var outputFilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".png"); Font font = SystemFonts.CreateFont("Arial", 10); // for scaling water mark size is largely ignored. using (var img2 = img.Clone(ctx => ApplyScalingWaterMarkSimple(ctx, font, "Gradio.Net", Color.HotPink, 5))) { img2.Save(outputFilePath); } return outputFilePath; } } static IImageProcessingContext ApplyScalingWaterMarkSimple(IImageProcessingContext processingContext, Font font, string text, Color color, float padding) { Size imgSize = processingContext.GetCurrentSize(); float targetWidth = imgSize.Width - (padding * 2); float targetHeight = imgSize.Height - (padding * 2); // Measure the text size FontRectangle size = TextMeasurer.MeasureSize(text, new TextOptions(font)); // Find out how much we need to scale the text to fill the space (up or down) float scalingFactor = Math.Min(targetWidth / size.Width, targetHeight / size.Height); // Create a new font Font scaledFont = new Font(font, scalingFactor * font.Size); var center = new PointF(imgSize.Width / 2, imgSize.Height / 2); var textOptions = new RichTextOptions(scaledFont) { Origin = center, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; return processingContext.DrawText(textOptions, text, color); }
示例效果
4、Chatbot
示例程式碼
App.Launch(await CreateBlocks()); async Task<Blocks> CreateBlocks() { using (var blocks = gr.Blocks()) { gr.Markdown("# Chatbot Demo"); var chatbot = gr.Chatbot(); var msg = gr.Textbox(placeholder:"Enter to Submit"); await msg.Submit(streamingFn: (input) => Respond(Textbox.Payload(input.Data[0]), Chatbot.Payload(input.Data[1])), inputs: new Component[] { msg, chatbot }, outputs: new Component[] { msg, chatbot }); return blocks; } } static async IAsyncEnumerable<Output> Respond(string message, IList<ChatbotMessagePair> chatHistory) { chatHistory.Add(new ChatbotMessagePair(message, "You typed: ")); for (int i = 0; i < message.Length; i++) { await Task.Delay(500); chatHistory.Last().AiMessage.TextMessage += message[i]; yield return gr.Output("", chatHistory); } }
示例效果
5、Progress
根據自己的需求,調整進度條程式碼,參考程式碼如下:
App.Launch(await CreateBlocks()); async Task<Blocks> CreateBlocks() { using (var blocks = gr.Blocks()) { gr.Markdown("# Progress Demo"); var load = gr.Button("Load"); var label = gr.Label(label: "Loader"); load.Click(LoadSet, outputs: new[] { label }); return blocks; } } static async Task<Output> LoadSet(Input input) { const int count = 24; input.Progress = gr.Progress(count); for (int i = 0; i < count; i++) { input.Progress.Report(i, desc: "Loading..."); await Task.Delay(100); } return gr.Output("Loaded"); }
示例效果
還有更多示例程式碼,可以檢視官方文件進行學習。
Gradio.NET 應用
對於 AI 的愛好者來說,Gradio.NET 提供了一個絕佳的機會,透過訪問 https://qwen.starworks.cc:88/,讓他們能夠與通義千問開源模型進行互動。
使用 Gradio.NET 打造你的 通義千問 AI 聊天機器人,具體如下圖所示:
這個 Web 應用不僅使用者體驗流暢,還能夠記住會話歷史,輕鬆識別語義,這一切都得益於其背後的先進技術。
該專案已開源,原始碼地址:https://github.com/sdcb/Sdcb.DashScope
具體程式碼講解,可以檢視原始碼。
專案地址
Github:https://github.com/feiyun0112/Gradio.Net
Demo:https://github.com/feiyun0112/Gradio.Net/blob/main/readme_files
AI聊天:https://github.com/sdcb/Sdcb.DashScope
總結
Gradio.NET 致力於成為 .NET 開發者 構建Web 應用的首選框架。它的設計理念是簡化開發過程,讓每個人都能輕鬆參與到 Web 應用的開發中來。
如果你對建立聊天機器人感興趣,可以試試上面這個開源專案,結合 Gradio.NET 開發自己的AI聊天,有需要的朋友們可以參考學習。
如果你覺得這篇文章對你有幫助,不妨點個贊支援一下!你的支援是我繼續分享知識的動力。如果有任何疑問或需要進一步的幫助,歡迎隨時留言。
也可以加入微信公眾號[DotNet技術匠] 社群,與其他熱愛技術的同行一起交流心得,共同成長!