Writing bindings(?) for libvips

Hey everyone!

I am currently working on a project where we are standardizing lots of really large Geographical rasters. While the raster package is intuitive and useful for doing practical work, aggregating huge raster images is taking way too much time.

I came across the libvips C/C++ library when searching for ways to handle large images. This seems like exactly what i need: Fast, multithreaded and widely used. Unfortunately, i don't think anyone has written bindings for this as an R package.

Now, i am not sure that this is even the way to go. Should i instead just do system calls to libvips? This seems precarious when trying to write code that works on multiple platforms, which is important for out project.

Looking forward to hearing your thoughts.
P

You can call it within python. That should make your code multi-platform, and you could do it inside an R Markdown document, I reckon?

Hey! Python / vips works excellent however, we are trying to write a package with functions using libvips. Is it possible to write functions in a package that call a python env. with all necessary packages?

Also, though unrelated to this forum, i need to figure out how to write my own image resizing kernel for vips. I am not sure if pyvips lets you use custom kernels.

well directly wrapping the c library is surely cleaner than wrapping a python library that wraps the c library. On the other hand you might be looking at quite a large project here... Maybe the sourcecode of the sf package helps as an inspiration? That one wraps a bunch of GIS libraries for R.

1 Like

Great! I was also looking at the source for Rgdal. Large project indeed, but it runs incredibly fast, so being able to aggregate with vips would mean very substantial speedups when working with these huge raster files.

Seems like deep water, but perhaps this is my chance to learn more about C / C++?

The Rcpp package for R has a pretty good reputation and provides a nice interface between R and c++. It is also pretty well documented. I would start there, but I"ve personally only done really trivial stuff with it and other people might be more qualified to point you in the right direction.

edit: The best approach would be to make an R package that wraps the whole libvips api and then use that in your project, but maybe it makes more sense for you to start small and only wrap those functions you really need right now for your project?

Agree. I have also used Rcpp for writing small functions, mostly for learning.
https://jcupitt.github.io/libvips/API/current/binding.md.html seems like a good place to start as well.

I have written packages that use Rcpp to wrap libraries (both system libraries and included in the package). I think it makes a lot of sense to go this way. Some questions: Which OS do you target? Is it for internal use or do you plan to distribute the package? See also this other post.

Hello, I help maintain libvips, I'd be very happy to help with a binding. There's a chapter in the docs about writing libvips bindings:

https://libvips.github.io/libvips/API/current/binding.md.html

tldr: use ffi to introspect the libvips shared library and translate R method calls and data types to libvips (this is the approach pyvips and ruby-vips take).

You can make a complete binding in only ~200 lines of code. pyvips is just the 220 lines here:

The rest of pyvips is a few simple convenience functions, something to auto-generate the docs, and a set of operator overloads.

Please open an issue on the libvips tracker if you have any questions.