Drawing
The Painter class allows you to draw either onto an
existing image or onto an empty canvas. Simply set it up via:
1import viren2d
2
3painter = viren2d.Painter()
4
5# Either create an empty canvas:
6painter.set_canvas_rgb(height=600, width=800, color='navy-blue')
7
8# Initialize with a given NumPy ndarray `np_image`:
9painter.set_canvas_image(image_numpy)
10
11# Or initialize from an image file:
12painter.set_canvas_filename('path/to/image.jpg')
viren2d::Painter. 1#include <viren2d/viren2d.h>
2
3auto painter = viren2d::CreatePainter();
4
5// Either create an empty canvas (H=600, W=800):
6painter->SetCanvas(600, 800, viren2d::Color(viren2d::NamedColor::NavyBlue));
7
8// Initialize with an existing viren2d::ImageBuffer:
9painter->SetCanvas(image_buffer);
10
11// Or initialize from an image file:
12painter->SetCanvas("path/to/image.jpg");
Once you’ve set up the painter, you can start drawing:
Finally, you simply retrieve the visualization result via
get_canvas(). This will yield an
ImageBuffer, which can easily be used with
common image processing libraries, such as NumPy or
OpenCV. The following examples show one option to retrieve your first
visualization from the Painter:
1# Get the visualization as `viren2d.ImageBuffer`:
2img_buffer = painter.get_canvas()
3
4# Convert to NumPy array (avoid unnecessary copy):
5import numpy as np
6img_np = np.array(img_buffer, copy=False)
7
8# For convenience, the canvas is also exposed as property of the painter:
9img_np = np.array(painter.canvas, copy=False)
viren2d::Painter. 1// Get a deep copy of the painter's canvas (for the following channel swap):
2viren2d::ImageBuffer canvas = painter->GetCanvas(true);
3
4// Optionally, if you've set up OpenCV, you can simply create a cv::Mat header
5// from the ImageBuffer. Note that OpenCV expects images in BGR(A) format:
6#include <opencv2/opencv.hpp>
7
8canvas.SwapChannels(0, 2);
9cv::Mat cv_buffer(
10 canvas.Height(), canvas.Width(),
11 CV_MAKETYPE(CV_8U, canvas.Channels()),
12 canvas.MutableData(), canvas.RowStride());
Tip
You can retrieve either a deep copy or a shared view on the
Painter’s canvas.
If you can ensure that the Painter instance is not
destroyed and you don’t concurrently change the canvas, you should prefer
the shared view because it avoids unnecessary memory allocation.
Refer to get_canvas() for details.
Note
As demonstrated by the example code above, the viren2d Python
API is simply a wrapper of the C++ API. Except for the naming conventions
(Snake case in Python vs. camel case in C++), both APIs are highly
similar.
Thus, the rest of this tutorial will mostly omit the C++ examples. The corresponding C++ counterpart will instead be mentioned in the API documentation of the Python bindings.