3个版本 (稳定)
8.15.1 | 2024年2月2日 |
---|---|
8.14.2 | 2023年6月22日 |
#130 in 图像
3.5MB
98K SLoC
libvips-rust-bindings
libvips的Rust绑定。由版本 8.14.2 生成。
这是libvips C库的安全包装。它基于C API和基于反射API的结果。
这个crate本身没有文档,但与libvips本身相比,它没有逻辑或特殊行为。所有在官方libvips 文档中描述的调用和类型都只是转换成Rust类型。所有默认值也得到尊重。
crate的编写方式
第一步是运行bindgen来生成对C libvips库的不安全调用。生成后,编译并执行C代码。此代码反射操作并将它们作为文本输出。然后解析这些文本并生成error.rs
和ops.rs
模块。
这些基本上是在生成的绑定之上的安全包装。虽然未广泛测试,但所有内存清理应该按预期工作。需要注意的是,操作名称中的所有“vips”前缀都已从名称中删除。
将绑定和生成的操作推送到crates.io,其中包含libvips的大部分可选依赖项。在调用依赖于这些子依赖项的函数时请小心(大多数与格式相关)。
贡献
ops.rs和error.rs(以及当然,bindings.rs)中的所有内容都是通过程序生成的。您需要将这些文件更改到构建器。然后,从generator
目录运行以下shell脚本。
$ ./build.sh # Builds the libvips-builder docker image
$ ./generate.sh # Actually generates the bindings
如何使用它
本库的主要实体是 VipsApp
结构体。它不存储任何信息,但只要它没有被销毁,vips 应该会按预期工作。
Vips 需要初始化和关闭,这个结构体负责这项工作,尽管您不必关闭它,当持有 VipsApp
结构体值的变量被销毁时,它将自动完成。
并非所有函数都已实现,所以如果您需要尚未提供的某些函数,请随时提交一个 PR 或问题(添加需要手动添加的函数相当直接)。
许多 vips 操作具有可选参数。这个库通过多种变体实现了这些可选参数。基本上,会有一个仅包含所需参数的常规调用和一个带有后缀 with_opts
的额外调用,后者将接受一个包含默认值的结构体。
这些默认值结构体的名称是以 class case
中的操作名称命名的,并加上后缀 Options
。所有这些结构体都实现了 Default
特性,因此您可以像这样构造它们,例如
let options = ops::Composite2Options {
x: 10,
y: 10,
.. Composite2Options::default()
}
目前错误消息没有被附加到错误本身。它们在 libvips 错误缓冲区中。VipsApps
结构体内部实现了错误缓冲区操作。
大多数(如果不是所有)vips 操作不会修改 VipsImage
对象,所以它们会返回一个新的对象。在这个库中实现的 VipsImage
会负责在它被销毁后释放内部指针。请注意,目前 VipsImage
对象不是线程安全的。我将调查发生了什么,并在未来提供解决方案。
示例
use libvips::{ops, VipsImage, VipsApp};
fn main() {
// this initializes the libvips library. it has to live as long as the application lives (or as long as you want to use the library within your app)
// you can't have multiple objects of this type and when it is dropped it will call the libvips functions to free all internal structures.
let app = VipsApp::new("Test Libvips", false).expect("Cannot initialize libvips");
//set number of threads in libvips's threadpool
app.concurrency_set(2);
// loads an image from file
let image = VipsImage::new_from_file("test.png").unwrap();
// will resized the image and return a new instance.
// libvips works most of the time with immutable objects, so it will return a new object
// the VipsImage struct implements Drop, which will free the memory
let resized = ops::resize(&image, 0.5).unwrap();
//optional parameters
let options = ops::JpegsaveOptions {
q: 90,
background: vec![255.0],
strip: true,
optimize_coding: true,
optimize_scans: true,
interlace: true,
..ops::JpegsaveOptions::default()
};
// alternatively you can use `jpegsave` that will use the default options
match ops::jpegsave_with_opts(&resized, "output.jpeg", &options) {
Err(_) => println!("error: {}", app.error_buffer().unwrap()),
Ok(_) => println!("Great Success!")
}
}