核心的gradio
库是一个Python库。但由于Python能够与外部进程进行交互,你也可以使用gradio
为用其他语言编写的程序创建用户界面。通过使用Python的subprocess
模块,你可以调用用C++、Rust或几乎任何其他语言编写的程序,使gradio
成为非Python应用程序的灵活用户界面层。
在这篇文章中,我们将介绍如何将gradio
与C++和Rust集成,使用Python的subprocess
模块来调用用这些语言编写的代码。我们还将讨论如何在R中使用Gradio,这要归功于reticulate R包,它使得在R中安装和导入Python模块成为可能。
让我们从一个简单的例子开始,将C++程序集成到Gradio应用中。假设我们有以下C++程序,用于将两个数字相加:
// add.cpp
#include <iostream>
int main() {
double a, b;
std::cin >> a >> b;
std::cout << a + b << std::endl;
return 0;
}
该程序从标准输入读取两个数字,将它们相加,并输出结果。
我们可以使用Python的subprocess
模块围绕这个C++程序构建一个Gradio界面。以下是相应的Python代码:
import gradio as gr
import subprocess
def add_numbers(a, b):
process = subprocess.Popen(
['./add'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
output, error = process.communicate(input=f"{a} {b}\n".encode())
if error:
return f"Error: {error.decode()}"
return float(output.decode().strip())
demo = gr.Interface(
fn=add_numbers,
inputs=[gr.Number(label="Number 1"), gr.Number(label="Number 2")],
outputs=gr.Textbox(label="Result")
)
demo.launch()
在这里,subprocess.Popen
用于执行编译后的 C++ 程序(add
),传递输入值并捕获输出。你可以通过运行以下命令来编译 C++ 程序:
g++ -o add add.cpp
这个例子展示了如何使用subprocess
从Python调用C++,并围绕它构建一个Gradio界面是多么容易。
现在,让我们来看另一个例子:调用一个Rust程序来对图像应用棕褐色滤镜。Rust代码可能如下所示:
// sepia.rs
extern crate image;
use image::{GenericImageView, ImageBuffer, Rgba};
fn sepia_filter(input: &str, output: &str) {
let img = image::open(input).unwrap();
let (width, height) = img.dimensions();
let mut img_buf = ImageBuffer::new(width, height);
for (x, y, pixel) in img.pixels() {
let (r, g, b, a) = (pixel[0] as f32, pixel[1] as f32, pixel[2] as f32, pixel[3]);
let tr = (0.393 * r + 0.769 * g + 0.189 * b).min(255.0);
let tg = (0.349 * r + 0.686 * g + 0.168 * b).min(255.0);
let tb = (0.272 * r + 0.534 * g + 0.131 * b).min(255.0);
img_buf.put_pixel(x, y, Rgba([tr as u8, tg as u8, tb as u8, a]));
}
img_buf.save(output).unwrap();
}
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() != 3 {
eprintln!("Usage: sepia <input_file> <output_file>");
return;
}
sepia_filter(&args[1], &args[2]);
}
这个Rust程序对图像应用了深褐色滤镜。它需要两个命令行参数:输入图像的路径和输出图像的路径。你可以使用以下命令编译这个程序:
cargo build --release
现在,我们可以从Python调用这个Rust程序,并使用Gradio来构建界面:
import gradio as gr
import subprocess
def apply_sepia(input_path):
output_path = "output.png"
process = subprocess.Popen(
['./target/release/sepia', input_path, output_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
process.wait()
return output_path
demo = gr.Interface(
fn=apply_sepia,
inputs=gr.Image(type="filepath", label="Input Image"),
outputs=gr.Image(label="Sepia Image")
)
demo.launch()
在这里,当用户上传图像并点击提交时,Gradio调用Rust二进制文件(sepia
)来处理图像,并将经过棕褐色滤镜处理的输出返回给Gradio。
此设置展示了如何将用Rust编写的性能关键或专用代码集成到Gradio界面中。
reticulate
)由于reticulate
包允许您直接在R中运行Python代码,因此将Gradio与R集成特别简单。让我们通过一个在R中使用Gradio的示例来了解。
安装
首先,你需要在R中安装reticulate
包:
install.packages("reticulate")
安装后,您可以使用该包直接从R脚本中运行Gradio。
library(reticulate)
py_install("gradio", pip = TRUE)
gr <- import("gradio") # import gradio as gr
构建一个Gradio应用程序
安装并导入gradio后,我们现在可以使用gradio的应用程序构建方法。让我们为一个返回问候语的R函数构建一个简单的应用程序
greeting <- \(name) paste("Hello", name)
app <- gr$Interface(
fn = greeting,
inputs = gr$Text(label = "Name"),
outputs = gr$Text(label = "Greeting"),
title = "Hello! 😃 👋"
)
app$launch(server_name = "localhost",
server_port = as.integer(3000))
感谢 @IfeanyiIdiaye 贡献本节内容。你可以在这里 here 查看更多示例,包括使用 Gradio Blocks 在 R 中构建机器学习应用程序。