Skip to content

AImageView#

Non-owning read-only image representation of some format.

Header:#include <AUI/Image/AImageView.h>
CMake:aui_link(my_target PUBLIC aui::image)

Public Methods#

constructor#


AImageView::AImageView(AByteBufferView data, size_t stride, glm::uvec2 size, APixelFormat format)

Constructs an image view with an explicit row stride.

This constructor creates a non-owning view over image data using the provided byte buffer and metadata. The stride (bytes per row) is explicitly specified, which allows the view to work with padded or externally aligned image memory.

Arguments
data
Non-owning byte buffer that contains the image pixels.
stride
Number of bytes between the start of consecutive rows.
size
Image dimensions in pixels (width, height).
format
Pixel format describing how to interpret each pixel.

AImageView::AImageView(AByteBufferView data, glm::uvec2 size, APixelFormat format)

Constructs an image view with tightly packed rows.

This constructor assumes the image rows are tightly packed in memory (no padding between rows). The stride is automatically computed as:

stride = bytesPerPixel() * width()

Use this overload only when the source image buffer has no row padding.

Arguments
data
Non-owning byte buffer that contains the image pixels.
size
Image dimensions in pixels (width, height).
format
Pixel format describing how to interpret each pixel.

buffer#


AByteBufferView AImageView::buffer()
Returns
Raw image pixel data.

bytesPerPixel#


std::uint8_t AImageView::bytesPerPixel()
Returns
Bytes per pixel.

convert#


template<auto /* APixelFormat::Value */ desiredFormat >
void AImageView::convert(aui::invocable<AFormattedImageView<desiredFormat> > auto&& consumer)

Converts (if needed) the image to the format desiredFormat known at compile time. The image is then passed to consumer.

Arguments
consumer
the consumer function that will accept the image view of format `desiredFormat`

Guarantees that the image passed into consumer is in the pixel format desiredFormat.

Two possible paths#

1) The image is already in desiredFormat#

Then the function avoids any work and passes the existing image view directly to consumer.

  • No conversion
  • No allocation
  • Minimal overhead
  • This is the fast path.

2) The image is in a different format#

Then the function:

  • creates an owning image object,
  • converts the pixels into desiredFormat,
  • passes the converted image view to consumer.

So the callback always receives the format it asked for.

Why it exists#

This is useful when you want code that only works with one pixel format, but the input may come in several formats. For example, you can write an image saver that expects RGBA and let convert handle the conversion if needed.

The function is a template on the target format, so the desired pixel format is known at compile time. That lets the API be type-safe and efficient.

In short#

“Give me an image in format X, and I’ll call your callback with an image view in format X, converting only if necessary.”


AImage AImageView::convert(APixelFormat desiredFormat)

Converts the image to the format desiredFormat known at runtime.

Arguments
desiredFormat
the image format to convert to
Returns
Owning, type-erased representation of an image in `desiredFormat`

In contrast to the template version of convert, this overload is easier to use at the cost of runtime overhead.

cropped#


AImage AImageView::cropped(glm::uvec2 position, glm::uvec2 size)

Crops the image, creating new image with the same format.

Arguments
position
offset
size
size of new image

data#


const char* AImageView::data()

Shortcut to buffer().data().

format#


APixelFormat AImageView::format()
Returns
Image pixel format.

Examples:

examples/ui/opengl_simple/src/main.cpp

OpenGL Example - Demonstrates how to integrate custom OpenGL rendering with AUI Framework.

          _new<MyRenderer>(state) AUI_OVERRIDE_STYLE { Expanding() },
          Horizontal::Expanding {
            Vertical {
              Vertical {
                Label { AUI_REACT(fmt::format("FPS: {:.1f}", *state->fps)) },
              } AUI_OVERRIDE_STYLE {
                    Padding(16_dp),
                    BackgroundSolid { AColor::WHITE.transparentize(0.5f) },
                    MinSize { 150_dp, {} },
                  },

get#


Color AImageView::get(glm::uvec2 position)

Retrieves pixel color data.

Arguments
position
position
Returns
color of specified pixel

This is a universal function that basically allows you to don't care about underlying image format representation. For performance critical code you may want to use visit method.

Specifying position out of image range causes assertion fail in debug or undefined behaviour.

Examples:

examples/app/minesweeper/src/Style.cpp

Minesweeper Game - Minesweeper game implementation driven by ass.

    }

    void setupConnections(AView* view, const _<AAssHelper>& helper) override {
        IAssSubSelector::setupConnections(view, helper);
        view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
        AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
    }
};
/// [CellSelector]
examples/app/game_of_life/src/main.cpp

Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.

        mFrame = AThreadPool::global() * [&] {
            for (int y = 0; y < mSize.y; ++y) {
                for (int x = 0; x < mSize.x; ++x) {
                    glm::ivec2 i { x, y };
                    get(mNextPopulation, i) = [&] {
                        auto around = cellsAround(i);
                        switch (around) {
                            default:
                                return CellState::DEAD;
                            case 2:

height#


unsigned AImageView::height()
Returns
Image height.

Examples:

examples/app/game_of_life/src/main.cpp

Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.

            mTexture = AWindow::current()->getRenderingContext()->renderer().getNewTexture();
        }

        CellsImage image(mCells->size());
        for (unsigned y = 0; y < image.height(); ++y) {
            for (unsigned x = 0; x < image.width(); ++x) {
                image.set(
                    { x, y },
                    AFormattedColorConverter(
                        (*mCells)[glm::ivec2(x, y)] == CellState::ALIVE

rawDataAt#


const char& AImageView::rawDataAt(glm::uvec2 position)

Retrieves reference to raw data at specified position.

Arguments
position
position
Returns
reference to raw pixel data

Specifying position out of image range causes assertion fail in debug or undefined behaviour.

size#


glm::uvec2 AImageView::size()
Returns
Image size.

Examples:

examples/7guis/cells/src/main.cpp

7GUIs Cells - Spreadsheet processor (Excel).

            AGridSplitter::Builder()
                    .noDefaultSpacers()
                    .withItems([&] {
                        AVector<AVector<_<AView>>> views;
                        views.resize(mState->spreadsheet.size().y + 1);
                        for (auto& c : views) {
                            c.resize(mState->spreadsheet.size().x + 1);
                        }

                        views[0][0] = _new<AView>();   // blank
examples/7guis/cells/src/Spreadsheet.h

7GUIs Cells - Spreadsheet processor (Excel).

#include "AUI/Common/AException.h"

class Spreadsheet {
public:
    explicit Spreadsheet(glm::uvec2 size) : mSize(size) {
        mCells.resize(size.x * size.y);
        for (auto& v : mCells) {
            v = std::make_unique<Cell>();
            v->spreadsheet = this;
        }
examples/7guis/cells/src/Functions.cpp

7GUIs Cells - Spreadsheet processor (Excel).

              return double(accumulator);
            } },
        { "IF",
            [](Ctx ctx) {
              if (ctx.args.size() != 3) {
                  throw AException("ARG");
              }
              auto condition = std::get_if<double>(&ctx.args[0]);
              if (condition == nullptr) {
                  throw AException("ARG0");
examples/ui/embedded_sdl/src/main.cpp

SDL3 - This code demonstrates how to integrate the AUI Framework with SDL3 to create a window with OpenGL rendering.

        setCustomDpiRatio(SDL_GetWindowDisplayScale(sdl_window));

        connect(getWindow()->touchscreenKeyboardShown, this, [this] {
            glm::ivec2 pos = getWindow()->getFocusedView()->getPositionInWindow();
            glm::ivec2 size = getWindow()->getFocusedView()->getSize();
            SDL_Rect rect;
            rect.x = pos.x;
            rect.y = pos.y;
            rect.w = size.x;
            rect.h = size.y;
examples/app/fractal/src/FractalView.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

    mTexture->bind();
    context.render.rectangle(ACustomShaderBrush {}, { 0, 0 }, getSize());
}

void FractalView::setSize(glm::ivec2 size) {
    AView::setSize(size);
    mShader.use();
    mShader.set(UNIFORM_RATIO, mAspectRatio = float(size.x) / float(size.y));
}
examples/app/game_of_life/src/main.cpp

Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.

using CellsImage = AFormattedImage<APixelFormat::RGBA_BYTE>;

class Cells : public AObject {
public:
    Cells(glm::ivec2 size) {
        mSize = size;
        for (auto s : { &mStorage, &mNextPopulation }) {
            s->resize(size.x * size.y);
        }

width#


unsigned AImageView::width()
Returns
Image width.

Examples:

examples/app/game_of_life/src/main.cpp

Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.

        }

        CellsImage image(mCells->size());
        for (unsigned y = 0; y < image.height(); ++y) {
            for (unsigned x = 0; x < image.width(); ++x) {
                image.set(
                    { x, y },
                    AFormattedColorConverter(
                        (*mCells)[glm::ivec2(x, y)] == CellState::ALIVE
                            ? AColor::WHITE