libcvd
draw.h
1 
2 #ifndef CVD_DRAW_H_
3 #define CVD_DRAW_H_
4 
5 #include <algorithm>
6 #include <cmath>
7 #include <cvd/convert_image.h>
8 #include <cvd/exceptions.h>
9 #include <cvd/image.h>
10 #include <cvd/image_ref.h>
11 #include <cvd/internal/builtin_components.h>
12 #include <cvd/internal/rgb_components.h>
13 #include <cvd/utility.h>
14 #include <vector>
15 
16 #include <cvd/config.h>
17 #ifdef CVD_HAVE_TOON
18 #include <TooN/TooN.h>
19 #endif
20 
21 namespace CVD
22 {
23 
24 namespace Exceptions
25 {
26 
29  namespace Draw
30  {
33  struct All : public CVD::Exceptions::All
34  {
35  using CVD::Exceptions::All::All;
36  };
37 
40  struct ImageRefNotInImage : public All
41  {
42  ImageRefNotInImage(const std::string& function)
43  : All("Input ImageRefs not in image in " + function) {};
44  };
45 
48  struct IncompatibleImageSizes : public All
49  {
50  IncompatibleImageSizes(const std::string& function)
51  : All("Incompatible image sizes in " + function) {};
52  };
53  };
54 };
55 
58 template <class T, unsigned int N = Pixel::Component<T>::count>
59 struct color
60 {
61 };
62 
66 template <class T>
67 struct color<T, 1>
68 {
69  typedef typename Pixel::Component<T>::type TComp;
71  inline static const T& black()
72  {
73  static T c;
74  Pixel::Component<T>::get(c, 0) = 0;
75  return c;
76  }
78  inline static const T& gray()
79  {
80  static T c;
82  return c;
83  }
85  inline static const T& white()
86  {
87  static T c;
89  return c;
90  }
91 };
92 
97 template <class T>
98 struct color<T, 3>
99 {
100  typedef typename Pixel::Component<T>::type TComp;
101  static const TComp hi;
102  inline static T make(const TComp& a, const TComp& b, const TComp& c)
103  {
104  T t;
105  Pixel::Component<T>::get(t, 0) = a;
106  Pixel::Component<T>::get(t, 1) = b;
107  Pixel::Component<T>::get(t, 2) = c;
108  return t;
109  }
110  inline static const T& black()
111  {
112  static const T c = make(0, 0, 0);
113  return c;
114  }
115  inline static const T& white()
116  {
117  static const T c = make(hi, hi, hi);
118  return c;
119  }
120  inline static const T& red()
121  {
122  static const T c = make(hi, 0, 0);
123  return c;
124  }
125  inline static const T& green()
126  {
127  static const T c = make(0, hi, 0);
128  return c;
129  }
130  inline static const T& blue()
131  {
132  static const T c = make(0, 0, hi);
133  return c;
134  }
135  inline static const T& cyan()
136  {
137  static const T c = make(0, hi, hi);
138  return c;
139  }
140  inline static const T& magenta()
141  {
142  static const T c = make(hi, 0, hi);
143  return c;
144  }
145  inline static const T& yellow()
146  {
147  static const T c = make(hi, hi, 0);
148  return c;
149  }
150  inline const T& shade(const T& c, double b)
151  {
152  return make((TComp)(Pixel::Component<T>::get(c, 0) * b), (TComp)(Pixel::Component<T>::get(c, 1) * b), (TComp)(Pixel::Component<T>::get(c, 2) * b));
153  }
154 };
155 template <class T>
157 
166 template <class T>
167 void drawLine(BasicImage<T>& im, double x1, double y1, double x2, double y2, const T& c)
168 {
169  double dx = x2 - x1;
170  double dy = y2 - y1;
171  int w = im.size().x;
172  int h = im.size().y;
173  double len = std::abs(dx) + std::abs(dy);
174  for(int t = 0; t <= len; t++)
175  {
176  int x = (int)(x1 + t / (len)*dx + 0.5);
177  int y = (int)(y1 + t / (len)*dy + 0.5);
178  if(x >= 0 && x < w && y >= 0 && y < h)
179  im[y][x] = c;
180  }
181 }
182 
189 template <class T>
190 void drawLine(BasicImage<T>& im, const ImageRef& p1, const ImageRef& p2, const T& c)
191 {
192  drawLine(im, double(p1.x), double(p1.y), double(p2.x), double(p2.y), c);
193 }
194 
195 #ifdef CVD_HAVE_TOON
196 template <class T>
203 void drawLine(BasicImage<T>& im, const TooN::Vector<2>& p1, const TooN::Vector<2>& p2, const T& c)
204 {
205  drawLine(im, p1[0], p1[1], p2[0], p2[1], c);
206 }
207 #endif
208 
216 template <class T>
217 void drawShape(BasicImage<T>& im, const ImageRef& offset, const std::vector<ImageRef>& points, const T& c)
218 {
219  for(unsigned int i = 0; i < points.size() - 1; i++)
220  drawLine(im, points[i] + offset, points[i + 1] + offset, c);
221  drawLine(im, points.back() + offset, points.front() + offset, c);
222 }
223 
232 template <class T, class PointIterator>
233 void drawShape(Image<T>& im, const ImageRef& offset,
234  PointIterator begin, PointIterator end, const T& c)
235 {
236  if(begin == end)
237  {
238  return;
239  }
240  PointIterator last(begin);
241  PointIterator it(begin);
242  ++it;
243  for(; it != end; it++)
244  {
245  drawLine(im, *last + offset, *(it) + offset, c);
246  last = it;
247  }
248  drawLine(im, (*last) + offset, (*begin) + offset, c);
249 }
250 
257 template <class T>
258 void drawBox(BasicImage<T>& im, const ImageRef& upperleft, const ImageRef& lowerright, const T& c)
259 {
260  drawLine(im, upperleft.x, upperleft.y, upperleft.x, lowerright.y, c);
261  drawLine(im, upperleft.x, upperleft.y, lowerright.x, upperleft.y, c);
262  drawLine(im, upperleft.x, lowerright.y, lowerright.x, lowerright.y, c);
263  drawLine(im, lowerright.x, upperleft.y, lowerright.x, lowerright.y, c);
264 }
265 
272 template <class T>
273 void drawCross(BasicImage<T>& im, const ImageRef& p, double len, const T& c)
274 {
275  drawLine(im, p.x - len, p.y, p.x + len, p.y, c);
276  drawLine(im, p.x, p.y - len, p.x, p.y + len, c);
277 }
278 
284 std::vector<ImageRef> getCircle(int radius);
285 
291 std::vector<ImageRef> getDisc(double radius);
292 
293 #if defined CVD_HAVE_TOON || defined DOXYGEN_IGNORE_INTERNAL
294 std::vector<ImageRef> getSolidEllipse(float r1, float r2, float theta);
302 #endif
303 
309 template <class S, class T, class U>
310 void joinImages(const Image<S>& a, const Image<T>& b, Image<U>& J)
311 {
312  int h = std::max(a.size().y, b.size().y);
313  J.resize(ImageRef(a.size().x + b.size().x, h));
314  CVD::copy(a, J, a.size());
315  CVD::copy(b, J, b.size(), ImageRef(), ImageRef(a.size().x, 0));
316  ImageRef blackBegin, blackEnd;
317  if(a.size().y < b.size().y)
318  {
319  blackBegin = ImageRef(0, a.size().y);
320  blackEnd = ImageRef(a.size().x, J.size().y);
321  }
322  else
323  {
324  blackBegin = ImageRef(a.size().x, b.size().y);
325  blackEnd = J.size();
326  }
327  for(int i = blackBegin.y; i < blackEnd.y; i++)
328  for(int j = blackBegin.x; j < blackEnd.x; j++)
329  J[i][j] = U();
330 }
331 
338 template <class S, class T, class U>
339 void combineImages(const Image<S>& a, const Image<T>& b, Image<U>& out, const ImageRef& dst = ImageRef_zero, ImageRef size = ImageRef(), const ImageRef& from = ImageRef_zero)
340 {
341  if(!a.in_image(dst))
342  throw Exceptions::Draw::ImageRefNotInImage("combineImages");
343  if(a.size() != out.size)
344  throw Exceptions::Draw::IncompatibleImageSizes("combineImages");
345 
346  if(size == ImageRef_zero)
347  size = b.size();
348 
349  if(size.x + dst.x >= a.size().x)
350  size.x = a.size().x - dst.x;
351  if(size.x + dst.x >= out.size().x)
352  size.x = out.size().x - dst.x;
353  if(size.y + dst.y >= a.size().y)
354  size.y = a.size().y - dst.y;
355  if(size.y + dst.y >= out.size().y)
356  size.y = out.size().y - dst.y;
357 
358  if(&a != &out)
359  {
360  CVD::copy(a, out, a.size());
361  }
362 
363  ImageRef sourceA = dst;
364  ImageRef sourceB = from;
365  ImageRef endA = dst + size;
366  ImageRef endB = from + size;
367 
368  out[sourceA] += b[sourceB];
369  while(sourceA.next(dst, endA))
370  {
371  sourceB.next(from, endB);
372  out[sourceA] += b[sourceB];
373  }
374 }
375 
376 };
377 #endif // CVD_DRAW_H_
All classes and functions are within the CVD namespace.
Definition: argb.h:6
ImageRef size() const
What is the size of this image?
Definition: image.h:557
Input images have incompatible dimensions.
Definition: draw.h:48
std::vector< ImageRef > getDisc(double radius)
returns coordinate for a disc of given radius around the origin.
Definition: draw.cc:29
void copy(const BasicImage< S > &in, BasicImage< T > &out, ImageRef size=ImageRef(-1, -1), ImageRef begin=ImageRef(), ImageRef dst=ImageRef())
Generic image copy function for copying sub rectangles of images into other images.
Definition: utility.h:30
bool next(const ImageRef &max)
Step to the next co-ordinate in the image (in horizontal scanline order).
Definition: image_ref.h:24
static const T & black()
returns pixel value corresponding to minimal saturation
Definition: draw.h:71
static const T & gray()
returns pixel value corresponding to 50% gray
Definition: draw.h:78
void resize(const ImageRef &size)
Resize the image (destroying the data).
Definition: image.h:731
void drawBox(BasicImage< T > &im, const ImageRef &upperleft, const ImageRef &lowerright, const T &c)
draws a box defined by the upper left and the lower right corners into an image
Definition: draw.h:258
traits type defining colors for pixel types
Definition: draw.h:59
int x
The x co-ordinate.
Definition: image_ref.h:172
Base class for all CVD exceptions.
Definition: exceptions.h:15
Definition: image_ref.h:29
void joinImages(const Image< S > &a, const Image< T > &b, Image< U > &J)
joins two images side-by-side to create a larger image, any remaining empty region will be blacked ou...
Definition: draw.h:310
A generic image class to manage a block of arbitrarily padded data as an image.
Definition: image.h:273
Base class for all Image_IO exceptions.
Definition: draw.h:33
int y
The y co-ordinate.
Definition: image_ref.h:173
A full image which manages its own data.
Definition: image.h:623
Input ImageRef not within image dimensions.
Definition: draw.h:40
Definition: builtin_components.h:38
std::vector< ImageRef > getCircle(int radius)
returns coordinate for a circle of given radius around the origin.
Definition: draw.cc:6
static const T & white()
returns pixel value corresponding to maximal saturation
Definition: draw.h:85
void drawCross(BasicImage< T > &im, const ImageRef &p, double len, const T &c)
draws a cross defined by center point and length of the arms into an image
Definition: draw.h:273
void combineImages(const Image< S > &a, const Image< T > &b, Image< U > &out, const ImageRef &dst=ImageRef_zero, ImageRef size=ImageRef(), const ImageRef &from=ImageRef_zero)
similar to copy but combines values from two source images into the output image. ...
Definition: draw.h:339
void drawShape(BasicImage< T > &im, const ImageRef &offset, const std::vector< ImageRef > &points, const T &c)
draws a polyline defined by a set of points into an image.
Definition: draw.h:217
Definition: pixel_traits.h:16
void drawLine(BasicImage< T > &im, double x1, double y1, double x2, double y2, const T &c)
draws a line defined by start and end coordinates with given color into an image. ...
Definition: draw.h:167