MVE - Multi-View Environment mve-devel
Loading...
Searching...
No Matches
image_drawing.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015, Simon Fuhrmann
3 * TU Darmstadt - Graphics, Capture and Massively Parallel Computing
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD 3-Clause license. See the LICENSE.txt file for details.
8 */
9
10#ifndef MVE_IMAGEDRAWING_HEADER
11#define MVE_IMAGEDRAWING_HEADER
12
13#include <algorithm>
14#include <cmath>
15
16#include "mve/defines.h"
17#include "mve/image.h"
18
21
27template <typename T>
28void
29draw_line (Image<T>& image, int64_t x1, int64_t y1, int64_t x2, int64_t y2,
30 T const* color);
31
37template <typename T>
38void
39draw_circle (Image<T>& image, int64_t x, int64_t y, int64_t radius,
40 T const* color);
41
46template <typename T>
47void
48draw_rectangle (Image<T>& image, int64_t x1, int64_t y1, int64_t x2, int64_t y2,
49 T const* color);
50
53
54/* ------------------------- Implementation ----------------------- */
55
58
59template <typename T>
60void
61draw_line (Image<T>& image, int64_t x0, int64_t y0, int64_t x1, int64_t y1,
62 T const* color)
63{
64 /* http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm */
65 int64_t const chans = image.channels();
66 int64_t const row_stride = image.width() * chans;
67
68 int64_t const dx = std::abs(x1 - x0);
69 int64_t const dy = std::abs(y1 - y0) ;
70 int64_t const sx = x0 < x1 ? 1 : -1;
71 int64_t const sy = y0 < y1 ? 1 : -1;
72 int64_t err = dx - dy;
73
74 T* ptr = &image.at(x0, y0, 0);
75 while (true)
76 {
77 std::copy(color, color + chans, ptr);
78 if (x0 == x1 && y0 == y1)
79 break;
80 int64_t const e2 = 2 * err;
81 if (e2 > -dy)
82 {
83 err -= dy;
84 x0 += sx;
85 ptr += sx * chans;
86 }
87 if (e2 < dx)
88 {
89 err += dx;
90 y0 += sy;
91 ptr += sy * row_stride;
92 }
93 }
94}
95
96
97template <typename T>
98void
99draw_circle (Image<T>& image, int64_t x, int64_t y, int64_t radius,
100 T const* color)
101{
102 /* http://en.wikipedia.org/wiki/Bresenham_circle */
103 int64_t const chans = image.channels();
104 int64_t const row_stride = image.width() * chans;
105 T* const ptr = &image.at(x, y, 0);
106 std::copy(color, color + chans, ptr - radius * row_stride);
107 std::copy(color, color + chans, ptr - radius * chans);
108 std::copy(color, color + chans, ptr + radius * chans);
109 std::copy(color, color + chans, ptr + radius * row_stride);
110
111 int64_t f = 1 - radius;
112 int64_t ddf_x = 1;
113 int64_t ddf_y = -2 * radius;
114 int64_t xi = 0;
115 int64_t yi = radius;
116 while (xi < yi)
117 {
118 if (f >= 0)
119 {
120 yi--;
121 ddf_y += 2;
122 f += ddf_y;
123 }
124 xi++;
125 ddf_x += 2;
126 f += ddf_x;
127
128 std::copy(color, color + chans, ptr + xi * chans + yi * row_stride);
129 std::copy(color, color + chans, ptr - xi * chans + yi * row_stride);
130 std::copy(color, color + chans, ptr + xi * chans - yi * row_stride);
131 std::copy(color, color + chans, ptr - xi * chans - yi * row_stride);
132 std::copy(color, color + chans, ptr + xi * row_stride + yi * chans);
133 std::copy(color, color + chans, ptr - xi * row_stride + yi * chans);
134 std::copy(color, color + chans, ptr + xi * row_stride - yi * chans);
135 std::copy(color, color + chans, ptr - xi * row_stride - yi * chans);
136 }
137}
138
139template <typename T>
140void
141draw_rectangle (Image<T>& image, int64_t x1, int64_t y1, int64_t x2, int64_t y2,
142 T const* color)
143{
144 if (x1 > x2)
145 std::swap(x1, x2);
146 if (y1 > y2)
147 std::swap(y1, y2);
148 x1 = std::max<int64_t>(0, x1);
149 x2 = std::max<int64_t>(0, x2);
150 x1 = std::min<int64_t>(image.width() - 1, x1);
151 x2 = std::min<int64_t>(image.width() - 1, x2);
152 y1 = std::max<int64_t>(0, y1);
153 y2 = std::max<int64_t>(0, y2);
154 y1 = std::min<int64_t>(image.height() - 1, y1);
155 y2 = std::min<int64_t>(image.height() - 1, y2);
156
157 int64_t const row_stride = image.width() * image.channels();
158 T* ptr = image.begin();
159 for (int64_t y = y1; y <= y2; ++y)
160 for (int64_t x = x1; x <= x2; ++x)
161 std::copy(color, color + image.channels(),
162 ptr + x * image.channels() + y * row_stride);
163}
164
167
168#endif /* MVE_IMAGEDRAWING_HEADER */
int64_t height(void) const
Returns the height of the image.
Definition image_base.h:207
int64_t channels(void) const
Returns the amount of channels in the image.
Definition image_base.h:213
int64_t width(void) const
Returns the width of the image.
Definition image_base.h:201
Multi-channel image class of arbitrary but homogenous data type.
Definition image.h:40
T const & at(int64_t index) const
Linear indexing of image data.
Definition image.h:307
T * begin(void)
Returns data pointer to beginning.
Definition image_base.h:472
#define MVE_IMAGE_NAMESPACE_END
Definition defines.h:17
#define MVE_NAMESPACE_BEGIN
Definition defines.h:13
#define MVE_IMAGE_NAMESPACE_BEGIN
Definition defines.h:16
#define MVE_NAMESPACE_END
Definition defines.h:14
void draw_line(Image< T > &image, int64_t x1, int64_t y1, int64_t x2, int64_t y2, T const *color)
Draws a line from (x0,y0) to (x1,y1) with given color on the image.
void draw_rectangle(Image< T > &image, int64_t x1, int64_t y1, int64_t x2, int64_t y2, T const *color)
Draws a rectangle from (x1,y1) to (x2,y2) on the image.
void draw_circle(Image< T > &image, int64_t x, int64_t y, int64_t radius, T const *color)
Draws a circle with midpoint (x,y) and given 'radius' on the image.
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.
Definition image.h:478