18个稳定版本
8.3.0 |
|
---|---|
1.7.0 | 2024年2月3日 |
1.6.1 | 2023年11月3日 |
1.5.1 | 2023年1月23日 |
1.1.2 | 2019年11月11日 |
#30 in 图像
904 每月下载量
在 2 crate 中使用
3MB
89K SLoC
libvips-rust-bindings
libvips的Rust绑定。从版本 version 8.14.5
生成。
这是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
对维护者的说明
crate的发布是手动完成的,并且在完成此操作后需要在仓库中更新 Cargo.lock 版本。一旦在仓库中添加了github actions,就可以在合并后发布。
如何使用它
本包的主要实体是VipsApp
结构体。它不存储任何信息,只要它没有被销毁,vips 应该能够按预期工作。
Vips需要初始化和关闭,这个结构体就负责这项工作,尽管您不必手动关闭它,当持有VipsApp
结构体值的变量被销毁时,它将自动完成。
并非所有函数都已实现,所以如果您需要尚未实现的某些功能,请随意提交一个PR或问题(添加需要手动实现的功能相对简单)。
许多vips操作都有可选参数。这个crate通过多种变体实现了这些操作。基本上,会有一个仅包含必要参数的常规调用和一个带有后缀with_opts
的附加调用,后者将接受一个包含默认值的结构体。
这些默认值的结构体名称是以class case
中的操作名称命名的,并加上后缀Options
。所有结构体都实现了Default
特质,所以您可以像这样构建它们,例如
let options = ops::Composite2Options {
x: 10,
y: 10,
.. Composite2Options::default()
}
目前错误消息没有被附加到错误本身上。它们位于libvips错误缓冲区中。错误缓冲区操作是在VipsApps
结构体中实现的。
大多数(如果不是所有)vips操作都不会修改VipsImage
对象,所以它们将返回一个新的对象。这个crate中对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 resize 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!")
}
}
依赖项
~0.3–0.9MB
~19K SLoC