| IOLink 1.11.0

Loading...
Searching...
No Matches
colorWheel.cpp

This code demonstrates how to draw a color wheel into a RGBA ImageView.

This code demonstrates how to draw a color wheel into a RGBA ImageView.The part outside the wheel is transparent, using alpha channel.

#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <vector>
#include <iolink/view/ImageViewFactory.h>
using namespace iolink;
static Vector3u8
hsvToRgb(double h, double s, double v)
{
double hp = h / 60.0;
double c = s * v;
double x = c * (1 - std::abs(std::fmod(hp, 2) - 1));
double m = v - c;
double r = 0, g = 0, b = 0;
if (hp <= 1)
{
r = c;
g = x;
}
else if (hp <= 2)
{
r = x;
g = c;
}
else if (hp <= 3)
{
g = c;
b = x;
}
else if (hp <= 4)
{
g = x;
b = c;
}
else if (hp <= 5)
{
r = x;
b = c;
}
else
{
r = c;
b = x;
}
Vector3d rgb_double{r, g, b};
rgb_double += Vector3d::createUniform(m);
rgb_double *= 255.0;
return Vector3u8(rgb_double);
}
std::shared_ptr<ImageView>
colorwheel(const VectorXu64& shape)
{
// first we can check if given shape has exactly 2 dimensions
if (shape.size() != 2)
{
throw std::runtime_error("colorwheel: shape must have 2 dimensions");
}
// To create a RGBA ImageView, the datatype of the image must have 4 components, and so
// should be be VEC4_XXX (with XXX: INT8, INT16, INT32, INT64, UINT8, ...)
// We choose VEC4_UINT8 as the datatype for this example.
const DataType dt = DataTypeId::VEC4_UINT8;
// create an image view in CPU memory
std::shared_ptr<ImageView> image = ImageViewFactory::allocate(shape, dt);
// indicate the created image is a 2D IMAGE with RGB color interpretation and alpha channel
image->setAxesInterpretation(ImageTypeId::IMAGE);
image->setImageInterpretation(ImageInterpretation::RGB);
image->setAlpha(true);
Vector2d center{static_cast<double>(shape[0]) / 2.0, static_cast<double>(shape[1]) / 2.0};
// draw the color wheel
// all pixels outside the wheel are transparent (alpha=0)
for (size_t y = 0; y < shape[1]; ++y)
{
for (size_t x = 0; x < shape[0]; ++x)
{
Vector2d position{static_cast<double>(x), static_cast<double>(y)};
Vector2d delta = position - center;
double r = delta.length();
if (r > center[0])
{
// write transparent pixel
Vector4u8 pixVal{0, 0, 0, 0};
image->write({x, y}, pixVal.data());
}
else
{
// determine HSV value for current pixel position
double h = std::atan2(delta[1], delta[0]) * 180 / M_PI + 180;
double s = r / center[0];
double v = 1;
// convert HSV to RGB
Vector3u8 rgb = hsvToRgb(h, s, v);
Vector4u8 rgba(rgb, 255);
// write RGBA pixel (with alpha = 255)
image->write({x, y}, rgba.data());
}
}
}
return image;
}
int
main(int argc, char** argv)
{
std::shared_ptr<ImageView> image = colorwheel({300, 300});
std::cout << "Created image: " << image->toString() << std::endl;
return EXIT_SUCCESS;
}
iolink::DataType
Stores information about a data type.
Definition DataType.h:162
iolink::Vector
An arithmetic vector.
Definition Vector.h:37
iolink::Vector::length
double length() const
Returns the vector's norm.
iolink::VectorX
A dynamically sized arithmetic vector.
Definition VectorX.h:18
iolink::VectorX::size
size_t size() const
Returns the size of the vector, which also correspond to vector number of dimension.
Definition VectorX.h:77
iolink
All IOLink symbols are enclosed in this namespace.
Definition ArrayX.h:8