Selene is a C++17 image representation, processing, and I/O library, focusing on ease of use and a clean, modern, type-safe API.
- Overview: Brief summary of the current feature set.
- Rationale: Why implement a new library for image representation, processing, and I/O?
Building & usage:
- Building the library: How to build from source.
- Dependencies: Description of optional dependencies.
- Installation: Installation using package managers (vcpkg/Conan).
- Usage: Using the built and/or installed library as a dependency in other projects.
Documentation & status:
- Documentation: API documentation & examples.
- Status: Supported compilers & status/roadmap of the library.
- Known issues: Known issues and possible workarounds.
- Contribution guidelines: How to contribute to the library.
- Strongly typed image and multi-channel pixel representations, and functions for image data access.
- Easy-to-use APIs to read and write images in JPEG, PNG, and TIFF formats (leveraging libjpeg, libpng, and libtiff).
- Basic image processing algorithms such as color conversions, pixel-wise operations, convolutions, rotation, etc.
- Lightweight and easy to build using CMake on Linux, MacOS, Windows.
A first impression of the API:
// Decode JPEG image data from disk
DynImage img_data = read_image(FileReader("example.jpg"));
assert(img_data.nr_channels() == 3 && img_data.nr_bytes_per_channel() == 1);
// Convert to strongly typed RGB image
Image<PixelRGB_8u> img_rgb = to_image<PixelRGB_8u>(std::move(img_data));
assert(img_rgb.width() > 400_px && img_rgb.height() > 350_px);
// Create non-owning view on part of the image
MutableImageView<PixelRGB_8u> img_part = view(img_rgb, {100_idx, 100_idx, 300_px, 250_px});
// Darken this part
for_each_pixel(img_part, [](auto& px){ px /= 4; });
// Flip this part horizontally
flip_horizontally_in_place(img_part);
// Apply a convolution to this part (1-D Gaussian kernel in x-direction, sigma=5.0, range: 3 std. deviations)
Kernel<double> kernel = gaussian_kernel(5.0, 3.0);
const auto img_part_copy = convolution_x<BorderAccessMode::Unchecked>(img_part, kernel);
// And copy the result back to the original image (i.e. to the view).
clone(img_part_copy, img_part);
// Convert whole image to RGBA, adding semi-transparent alpha channel
const Image<PixelRGBA_8u> img_rgba =
convert_image<PixelFormat::RGBA>(img_rgb, std::uint8_t{192});
// Encode in-memory to PNG
std::vector<std::uint8_t> encoded_png_data;
write_image(to_dyn_image_view(img_rgba), ImageFormat::PNG,
VectorWriter(encoded_png_data));
// Write encoded binary data to disk (or do something else with it...)
write_data_contents("example_out.png", encoded_png_data);
Building from source "at head" using CMake is the recommended way to use Selene (see Building the library). But the library is also available as a
- Conan package on Bintray
- vcpkg port
Selene's own dependencies can be installed using
besides OS level package managers or from source.
Please send me a message if you're using Selene. I would love to know what you think of it, and what your use cases are! Contributions are also very encouraged; see here for more information.