Skip to content

kmhofmann/selene

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Selene

Build Status

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:

Summary

  • 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.

Example

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);

Package managed

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

Selene's own dependencies can be installed using

besides OS level package managers or from source.

Feedback encouraged

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.