crow

Utility library


Project maintained by CaptainCrowbar Hosted on GitHub Pages — Theme by mattgraham

Images

Crow Library by Ross Smith

#include "crow/image.hpp"
namespace Crow;

Contents

Supporting types

using Point = Int2;

Used for pixel coordinates.

enum class ImageFlags: int {
    none    = 0,
    invert  = 1,
    pma     = 2,
}

Bitmask flags indicating properties of an image. Images are normally stored top down; they will be stored bottom up if the invert flag is used. Pixel data will be assumed to include premultiplied alpha if the pma flag is used.

enum class ImageResize: int {
    none    = 0,
    unlock  = 1,
    wrap    = 2,
}

Bitmask flags controlling the behaviour of the resize() function.

class ImageIoError:
public std::runtime_error {
    Path file() const noexcept;
};

This is thrown when one of the image I/O functions encounters an error. The name of the offending file will be supplied if possible.

struct ImageInfo {
    Point shape = Point::null();
    int channels = 0;
    int bits_per_channel = 0;
    bool has_alpha = false;
    bool is_hdr = false;
    explicit operator bool() const noexcept;
    std::string str() const;
};
std::ostream& operator<<(std::ostream& out, const ImageInfo& info);

Information about an image file. The boolean operator is true if the shape is not a null vector, indicating that a file has been successfully queried.

Image class

template <ColourType CT = Rgbaf, ImageFlags Flags = ImageFlags::none>
    class Image;

The image class.

Member types

class Image::iterator {
    iterator& move(int axis, int distance = 1) noexcept;
    Point pos() const noexcept;
};
class Image::const_iterator {
    const_iterator& move(int axis, int distance = 1) noexcept;
    Point pos() const noexcept;
};

Bidirectional iterators over the image’s pixels. Iterators have two additional member functions:

Iterators can be considered to exist in an infinite plane (bounded in practise by the range of an int); moving an iterator outside the bounds of the image using move() is safe. Behaviour is undefined if any of operator*(), operator++(), pos(), or the comparison operators are called on an off-image iterator.

using Image::channel_type = CT::value_type;
using Image::colour_space = CT::colour_space;
using Image::colour_type = CT;

Properties of the pixel type.

Constants

static constexpr int channels = CT::channels;
static constexpr ColourLayout colour_layout = CL;
static constexpr bool has_alpha = CT::has_alpha;
static constexpr bool is_hdr = CT::is_hdr;
static constexpr bool is_linear = CT::is_linear;

Properties of the pixel type.

static constexpr bool is_bottom_up;
static constexpr bool is_top_down;

Indicate whether the image is laid out top-down or bottom-up in memory.

static constexpr bool is_premultiplied;

True if the image uses premultiplied alpha.

Life cycle functions

Image::Image() noexcept;

The default constructor creates an empty image with zero width and height.

explicit Image::Image(Point shape);
Image::Image(Point shape, CT c);
Image::Image(int w, int h);
Image::Image(int w, int h, CT c);

Create an image with the specified dimensions. If a colour is supplied, the new image will be filled with that colour; otherwise, the pixel data is left uninitialized. These will throw std::invalid_argument if either dimension is negative, or if one is zero but the other is not.

Image::Image(const Image& img);
Image::Image(Image&& img) noexcept;
Image::~Image() noexcept;
Image& Image::operator=(const Image& img);
Image& Image::operator=(Image&& img) noexcept;

Other life cycle functions.

Pixel access functions

CT& Image::operator[](Point p) noexcept;
const CT& Image::operator[](Point p) const noexcept;
CT& Image::operator()(int x, int y) noexcept;
const CT& Image::operator()(int x, int y) const noexcept;

Reference to a specific pixel. Behaviour is undefined if the coordinates are out of bounds.

iterator Image::begin() noexcept;
const_iterator Image::begin() const noexcept;
iterator Image::end() noexcept;
const_iterator Image::end() const noexcept;

Iterators over the image’s pixels. The begin() iterator is the same pixel returned by locate(0,0).

iterator Image::bottom_left() noexcept;
const_iterator Image::bottom_left() const noexcept;
iterator Image::bottom_right() noexcept;
const_iterator Image::bottom_right() const noexcept;
iterator Image::top_left() noexcept;
const_iterator Image::top_left() const noexcept;
iterator Image::top_right() noexcept;
const_iterator Image::top_right() const noexcept;

These return iterators pointing to the pixel at one corner of the image. Behaviour is undefined if the image is empty.

CT* Image::pixel_data() noexcept;
const CT* Image::pixel_data() const noexcept;
channel_type* Image::channel_data() noexcept;
const channel_type* Image::channel_data() const noexcept;

Pointers to the image data.

iterator Image::locate(Point p) noexcept;
const_iterator Image::locate(Point p) const noexcept;
iterator Image::locate(int x, int y) noexcept;
const_iterator Image::locate(int x, int y) const noexcept;

These return an iterator pointing to the pixel at the specified coordinates. The iterator returned by locate(0,0) will match either top_left() or bottom_left(), depending on whether the image is stored top-down or bottom-up. Behaviour is undefined if the coordinates are out of bounds.

Conversion functions

Image<CT, [modified flags]> Image::multiply_alpha() const;
Image<CT, [modified flags]> Image::unmultiply_alpha() const;

Convert a non-premultiplied image into a premultiplied-alpha image, or vice versa. The returned image type has the opposite premultiplication flag. These are only defined if CT::can_premultiply is true.

template <typename C1, ImageFlags F1, typename C2, ImageFlags F2>
    void convert_image(const Image<C1, F1>& in, Image<C2, F2>& out);

Convert an image from one format to another.

I/O functions

The current implementation uses Sean Barrett’s STB library for image I/O.

void Image::load(const Path& file);

Load an image from a file. Supported image types are BMP, GIF, HDR/RGBE, JPEG, PIC, PNG, PNM, PSD, and TGA (not all features are supported for some formats). Input channel data can be 32-bit floating point for HDR/RGBE, 8-bit or 16-bit integer for all other formats. This will throw ImageIoError if the file does not exist, the image was not in a supported format, the image was too big for the STB library to load (the size limit is about 1-2 GB depending on format), or an I/O error occurs.

void Image::save(const Path& file, int quality = 90) const;

Save an image to a file. The image format is deduced from the file name suffix. Supported formats are BMP, HDR/RGBE, JPEG, PNG, and TGA. For JPEG images, the quality setting is clamped to [1,100]; for other formats the quality argument is ignored. This will throw ImageIoError if the image format is not supported or an I/O error occurs.

ImageInfo query_image(const Path& file) noexcept;

Queries an image file for information about the stored image. File formats supported are the same as for Image::load(). This will return a null ImageInfo if the file is not found or is not in a recognisable format.

Image size and shape functions

bool Image::empty() const noexcept;

True if the image is empty (both dimensions are zero).

void Image::reset(Point new_shape);
void Image::reset(Point new_shape, CT c);
void Image::reset(int w, int h);
void Image::reset(int w, int h, CT c);

Replace the image with a new image with the specified dimensions, discarding the image’s current contents. If a colour is supplied, the new image will be filled with that colour; otherwise, the pixel data is left uninitialized. These will throw std::invalid_argument if either dimension is negative, or if one is zero but the other is not.

void Image::resize(Point new_shape,
    ImageResize flags = ImageResize::none);
void Image::resize(double scale,
    ImageResize flags = ImageResize::none);
Image Image::resized(Point new_shape,
    ImageResize flags = ImageResize::none) const;
Image Image::resized(double scale,
    ImageResize flags = ImageResize::none) const;

Resample the image to a new set of dimensions. The resize() functions modify the image in place; the resized() functions return a new image. The first version of each function accepts a new width and height in pixels; the second version accepts a floating point scale factor(the new dimensions will be rounded to the nearest integer).

In the absence of the unlock flag, either of the new_shape dimensions (but not both) can be zero; the zero dimension will be scaled in proportion to the other dimension (rounded to the nearest integer). If both dimensions are set, the default behaviour is to scale the image to the largest size that will fit within the given dimensions. If the unlock flag is set, both of the new_shape dimensions are taken literally, which may change the aspect ratio of the image. The unlock flag has no effect on the scale based functions.

The wrap flag treats the image as wrapped around in both directions when interpolating edge values.

The new_shape based functions will throw std::invalid_argument if both dimensions are zero or either dimension is negative, or if either dimension is zero when the unlock flag is used. The scale based functions will throw std::invalid_argument if the scale is zero or negative.

Box_i2 Image::extent() const noexcept;
Point Image::shape() const noexcept;
int Image::width() const noexcept;
int Image::height() const noexcept;

Query the dimensions of the image. The box returned by extent() has its base at the origin and its dimensions equal to shape().

size_t Image::size() const noexcept;
size_t Image::bytes() const noexcept;

The size of the image, in pixels or bytes.

Other member functions

void Image::clear() noexcept;

Resets the Image object to an empty image. Equivalent to reset(0,0).

void Image::fill(CT c) noexcept;

Fills all pixels with a uniform colour.

Image Image::segment(Box_i2 box) const;

Returns a copy of a rectangular segment of the image. This will throw std::invalid_argument if part of the rectangle is outside the bounds of the image.

void Image::swap(Image& img) noexcept;
void swap(Image& a, Image& b) noexcept;

Swap two images.

Comparison operators

bool operator==(const Image& a, const Image& b) noexcept;
bool operator!=(const Image& a, const Image& b) noexcept;

These perform a full comparison on the pixel data of the images.