1 2 3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 5<html xmlns="http://www.w3.org/1999/xhtml"> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 9 <title>Examples - Boost.GIL documentation</title> 10 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> 11 <link rel="stylesheet" href="../_static/style.css" type="text/css" /> 12 <script type="text/javascript"> 13 var DOCUMENTATION_OPTIONS = { 14 URL_ROOT: '../', 15 VERSION: '', 16 COLLAPSE_MODINDEX: false, 17 FILE_SUFFIX: '.html' 18 }; 19 </script> 20 <script type="text/javascript" src="../_static/jquery.js"></script> 21 <script type="text/javascript" src="../_static/underscore.js"></script> 22 <script type="text/javascript" src="../_static/doctools.js"></script> 23 <link rel="index" title="Index" href="../genindex.html" /> 24 <link rel="search" title="Search" href="../search.html" /> 25 <link rel="top" title="Boost.GIL documentation" href="../index.html" /> 26 <link rel="up" title="Design Guide" href="index.html" /> 27 <link rel="next" title="Technicalities" href="technicalities.html" /> 28 <link rel="prev" title="Metafunctions" href="metafunctions.html" /> 29 </head> 30 <body> 31 <div class="header"> 32 <table border="0" cellpadding="7" cellspacing="0" width="100%" summary= 33 "header"> 34 <tr> 35 <td valign="top" width="300"> 36 <h3><a href="../index.html"><img 37 alt="C++ Boost" src="../_static/gil.png" border="0"></a></h3> 38 </td> 39 40 <td > 41 <h1 align="center"><a href="../index.html"></a></h1> 42 </td> 43 <td> 44 <div id="searchbox" style="display: none"> 45 <form class="search" action="../search.html" method="get"> 46 <input type="text" name="q" size="18" /> 47 <input type="submit" value="Search" /> 48 <input type="hidden" name="check_keywords" value="yes" /> 49 <input type="hidden" name="area" value="default" /> 50 </form> 51 </div> 52 <script type="text/javascript">$('#searchbox').show(0);</script> 53 </td> 54 </tr> 55 </table> 56 </div> 57 <hr/> 58 <div class="content"> 59 <div class="navbar" style="text-align:right;"> 60 61 62 <a class="prev" title="Metafunctions" href="metafunctions.html"><img src="../_static/prev.png" alt="prev"/></a> 63 <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a> 64 <a class="next" title="Technicalities" href="technicalities.html"><img src="../_static/next.png" alt="next"/></a> 65 66 </div> 67 68 <div class="section" id="examples"> 69<h1>Examples</h1> 70<div class="contents local topic" id="contents"> 71<ul class="simple"> 72<li><a class="reference internal" href="#pixel-level-operations" id="id1">Pixel-level Operations</a></li> 73<li><a class="reference internal" href="#resizing-image-canvas" id="id2">Resizing image canvas</a></li> 74<li><a class="reference internal" href="#histogram" id="id3">Histogram</a></li> 75<li><a class="reference internal" href="#using-image-views" id="id4">Using image views</a></li> 76</ul> 77</div> 78<div class="section" id="pixel-level-operations"> 79<h2><a class="toc-backref" href="#id1">Pixel-level Operations</a></h2> 80<p>Here are some operations you can do with pixel values, pixel pointers and 81pixel references:</p> 82<div class="highlight-cpp"><div class="highlight"><pre><span class="n">rgb8_pixel_t</span> <span class="nf">p1</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span> <span class="c1">// make a red RGB pixel</span> 83<span class="n">bgr8_pixel_t</span> <span class="n">p2</span> <span class="o">=</span> <span class="n">p1</span><span class="p">;</span> <span class="c1">// RGB and BGR are compatible and the channels will be properly mapped.</span> 84<span class="n">assert</span><span class="p">(</span><span class="n">p1</span><span class="o">==</span><span class="n">p2</span><span class="p">);</span> <span class="c1">// p2 will also be red.</span> 85<span class="n">assert</span><span class="p">(</span><span class="n">p2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">!=</span><span class="n">p1</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="c1">// operator[] gives physical channel order (as laid down in memory)</span> 86<span class="n">assert</span><span class="p">(</span><span class="n">semantic_at_c</span><span class="o"><</span><span class="mi">0</span><span class="o">></span><span class="p">(</span><span class="n">p1</span><span class="p">)</span><span class="o">==</span><span class="n">semantic_at_c</span><span class="o"><</span><span class="mi">0</span><span class="o">></span><span class="p">(</span><span class="n">p2</span><span class="p">));</span> <span class="c1">// this is how to compare the two red channels</span> 87<span class="n">get_color</span><span class="p">(</span><span class="n">p1</span><span class="p">,</span><span class="n">green_t</span><span class="p">())</span> <span class="o">=</span> <span class="n">get_color</span><span class="p">(</span><span class="n">p2</span><span class="p">,</span><span class="n">blue_t</span><span class="p">());</span> <span class="c1">// channels can also be accessed by name</span> 88 89<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">r</span><span class="p">;</span> 90<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">g</span><span class="p">;</span> 91<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">b</span><span class="p">;</span> 92<span class="n">rgb8c_planar_ptr_t</span> <span class="nf">ptr</span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="n">g</span><span class="p">,</span><span class="n">b</span><span class="p">);</span> <span class="c1">// constructing const planar pointer from const pointers to each plane</span> 93 94<span class="n">rgb8c_planar_ref_t</span> <span class="n">ref</span><span class="o">=*</span><span class="n">ptr</span><span class="p">;</span> <span class="c1">// just like built-in reference, dereferencing a planar pointer returns a planar reference</span> 95 96<span class="n">p2</span><span class="o">=</span><span class="n">ref</span><span class="p">;</span> <span class="n">p2</span><span class="o">=</span><span class="n">p1</span><span class="p">;</span> <span class="n">p2</span><span class="o">=</span><span class="n">ptr</span><span class="p">[</span><span class="mi">7</span><span class="p">];</span> <span class="n">p2</span><span class="o">=</span><span class="n">rgb8_pixel_t</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">);</span> <span class="c1">// planar/interleaved references and values to RGB/BGR can be freely mixed</span> 97 98<span class="c1">//rgb8_planar_ref_t ref2; // compile error: References have no default constructors</span> 99<span class="c1">//ref2=*ptr; // compile error: Cannot construct non-const reference by dereferencing const pointer</span> 100<span class="c1">//ptr[3]=p1; // compile error: Cannot set the fourth pixel through a const pointer</span> 101<span class="c1">//p1 = pixel<float, rgb_layout_t>();// compile error: Incompatible channel depth</span> 102<span class="c1">//p1 = pixel<bits8, rgb_layout_t>();// compile error: Incompatible color space (even though it has the same number of channels)</span> 103<span class="c1">//p1 = pixel<bits8,rgba_layout_t>();// compile error: Incompatible color space (even though it contains red, green and blue channels)</span> 104</pre></div> 105</div> 106<p>Here is how to use pixels in generic code:</p> 107<div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">GrayPixel</span><span class="p">,</span> <span class="k">typename</span> <span class="n">RGBPixel</span><span class="o">></span> 108<span class="kt">void</span> <span class="n">gray_to_rgb</span><span class="p">(</span><span class="k">const</span> <span class="n">GrayPixel</span><span class="o">&</span> <span class="n">src</span><span class="p">,</span> <span class="n">RGBPixel</span><span class="o">&</span> <span class="n">dst</span><span class="p">)</span> 109<span class="p">{</span> 110 <span class="n">gil_function_requires</span><span class="o"><</span><span class="n">PixelConcept</span><span class="o"><</span><span class="n">GrayPixel</span><span class="o">></span> <span class="o">></span><span class="p">();</span> 111 <span class="n">gil_function_requires</span><span class="o"><</span><span class="n">MutableHomogeneousPixelConcept</span><span class="o"><</span><span class="n">RGBPixel</span><span class="o">></span> <span class="o">></span><span class="p">();</span> 112 113 <span class="k">typedef</span> <span class="k">typename</span> <span class="n">color_space_type</span><span class="o"><</span><span class="n">GrayPixel</span><span class="o">>::</span><span class="n">type</span> <span class="n">gray_cs_t</span><span class="p">;</span> 114 <span class="k">static_assert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">is_same</span><span class="o"><</span><span class="n">gray_cs_t</span><span class="p">,</span><span class="n">gray_t</span><span class="o">>::</span><span class="n">value</span><span class="p">,</span> <span class="s">""</span><span class="p">);</span> 115 116 <span class="k">typedef</span> <span class="k">typename</span> <span class="n">color_space_type</span><span class="o"><</span><span class="n">RGBPixel</span><span class="o">>::</span><span class="n">type</span> <span class="n">rgb_cs_t</span><span class="p">;</span> 117 <span class="k">static_assert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">is_same</span><span class="o"><</span><span class="n">rgb_cs_t</span><span class="p">,</span><span class="n">rgb_t</span><span class="o">>::</span><span class="n">value</span><span class="p">,</span> <span class="s">""</span><span class="p">);</span> 118 119 <span class="k">typedef</span> <span class="k">typename</span> <span class="n">channel_type</span><span class="o"><</span><span class="n">GrayPixel</span><span class="o">>::</span><span class="n">type</span> <span class="n">gray_channel_t</span><span class="p">;</span> 120 <span class="k">typedef</span> <span class="k">typename</span> <span class="n">channel_type</span><span class="o"><</span><span class="n">RGBPixel</span><span class="o">>::</span><span class="n">type</span> <span class="n">rgb_channel_t</span><span class="p">;</span> 121 122 <span class="n">gray_channel_t</span> <span class="n">gray</span> <span class="o">=</span> <span class="n">get_color</span><span class="p">(</span><span class="n">src</span><span class="p">,</span><span class="n">gray_color_t</span><span class="p">());</span> 123 <span class="n">static_fill</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="n">channel_convert</span><span class="o"><</span><span class="n">rgb_channel_t</span><span class="o">></span><span class="p">(</span><span class="n">gray</span><span class="p">));</span> 124<span class="p">}</span> 125 126<span class="c1">// example use patterns:</span> 127 128<span class="c1">// converting gray l-value to RGB and storing at (5,5) in a 16-bit BGR interleaved image:</span> 129<span class="n">bgr16_view_t</span> <span class="n">b16</span><span class="p">(...);</span> 130<span class="n">gray_to_rgb</span><span class="p">(</span><span class="n">gray8_pixel_t</span><span class="p">(</span><span class="mi">33</span><span class="p">),</span> <span class="n">b16</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mi">5</span><span class="p">));</span> 131 132<span class="c1">// storing the first pixel of an 8-bit grayscale image as the 5-th pixel of 32-bit planar RGB image:</span> 133<span class="n">rgb32f_planar_view_t</span> <span class="n">rpv32</span><span class="p">;</span> 134<span class="n">gray8_view_t</span> <span class="nf">gv8</span><span class="p">(...);</span> 135<span class="n">gray_to_rgb</span><span class="p">(</span><span class="o">*</span><span class="n">gv8</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">rpv32</span><span class="p">[</span><span class="mi">5</span><span class="p">]);</span> 136</pre></div> 137</div> 138<p>As the example shows, both the source and the destination can be references or 139values, planar or interleaved, as long as they model <code class="docutils literal"><span class="pre">PixelConcept</span></code> and 140<code class="docutils literal"><span class="pre">MutablePixelConcept</span></code> respectively.</p> 141</div> 142<div class="section" id="resizing-image-canvas"> 143<h2><a class="toc-backref" href="#id2">Resizing image canvas</a></h2> 144<p>Resizing an image canvas means adding a buffer of pixels around existing 145pixels. Size of canvas of an image can never be smaller than the image itself.</p> 146<p>Suppose we want to convolve an image with multiple kernels, the largest of 147which is 2K+1 x 2K+1 pixels. It may be worth creating a margin of K pixels 148around the image borders. Here is how to do it:</p> 149<div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">SrcView</span><span class="p">,</span> <span class="c1">// Models ImageViewConcept (the source view)</span> 150 <span class="k">typename</span> <span class="n">DstImage</span><span class="o">></span> <span class="c1">// Models ImageConcept (the returned image)</span> 151<span class="kt">void</span> <span class="n">create_with_margin</span><span class="p">(</span><span class="k">const</span> <span class="n">SrcView</span><span class="o">&</span> <span class="n">src</span><span class="p">,</span> <span class="kt">int</span> <span class="n">k</span><span class="p">,</span> <span class="n">DstImage</span><span class="o">&</span> <span class="n">result</span><span class="p">)</span> 152<span class="p">{</span> 153 <span class="n">gil_function_requires</span><span class="o"><</span><span class="n">ImageViewConcept</span><span class="o"><</span><span class="n">SrcView</span><span class="o">></span> <span class="o">></span><span class="p">();</span> 154 <span class="n">gil_function_requires</span><span class="o"><</span><span class="n">ImageConcept</span><span class="o"><</span><span class="n">DstImage</span><span class="o">></span> <span class="o">></span><span class="p">();</span> 155 <span class="n">gil_function_requires</span><span class="o"><</span><span class="n">ViewsCompatibleConcept</span><span class="o"><</span><span class="n">SrcView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">DstImage</span><span class="o">::</span><span class="n">view_t</span><span class="o">></span> <span class="o">></span><span class="p">();</span> 156 157 <span class="n">result</span><span class="o">=</span><span class="n">DstImage</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">,</span> <span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">);</span> 158 <span class="k">typename</span> <span class="n">DstImage</span><span class="o">::</span><span class="n">view_t</span> <span class="n">centerImg</span><span class="o">=</span><span class="n">subimage_view</span><span class="p">(</span><span class="n">view</span><span class="p">(</span><span class="n">result</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">(),</span><span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">());</span> 159 <span class="n">std</span><span class="o">::</span><span class="n">copy</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">src</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">centerImg</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span> 160<span class="p">}</span> 161</pre></div> 162</div> 163<p>We allocated a larger image, then we used <code class="docutils literal"><span class="pre">subimage_view</span></code> to create a 164shallow image of its center area of top left corner at (k,k) and of identical 165size as <code class="docutils literal"><span class="pre">src</span></code>, and finally we copied <code class="docutils literal"><span class="pre">src</span></code> into that center image. If the 166margin needs initialization, we could have done it with <code class="docutils literal"><span class="pre">fill_pixels</span></code>. Here 167is how to simplify this code using the <code class="docutils literal"><span class="pre">copy_pixels</span></code> algorithm:</p> 168<div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">SrcView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">DstImage</span><span class="o">></span> 169<span class="kt">void</span> <span class="n">create_with_margin</span><span class="p">(</span><span class="k">const</span> <span class="n">SrcView</span><span class="o">&</span> <span class="n">src</span><span class="p">,</span> <span class="kt">int</span> <span class="n">k</span><span class="p">,</span> <span class="n">DstImage</span><span class="o">&</span> <span class="n">result</span><span class="p">)</span> 170<span class="p">{</span> 171 <span class="n">result</span><span class="p">.</span><span class="n">recreate</span><span class="p">(</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">,</span> <span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">()</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">k</span><span class="p">);</span> 172 <span class="n">copy_pixels</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">subimage_view</span><span class="p">(</span><span class="n">view</span><span class="p">(</span><span class="n">result</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="n">src</span><span class="p">.</span><span class="n">width</span><span class="p">(),</span><span class="n">src</span><span class="p">.</span><span class="n">height</span><span class="p">()));</span> 173<span class="p">}</span> 174</pre></div> 175</div> 176<p>(Note also that <code class="docutils literal"><span class="pre">image::recreate</span></code> is more efficient than <code class="docutils literal"><span class="pre">operator=</span></code>, as 177the latter will do an unnecessary copy construction). Not only does the above 178example work for planar and interleaved images of any color space and pixel 179depth; it is also optimized. GIL overrides <code class="docutils literal"><span class="pre">std::copy</span></code> - when called on two 180identical interleaved images with no padding at the end of rows, it simply 181does a <code class="docutils literal"><span class="pre">memmove</span></code>. For planar images it does <code class="docutils literal"><span class="pre">memmove</span></code> for each channel. 182If one of the images has padding, (as in our case) it will try to do 183<code class="docutils literal"><span class="pre">memmove</span></code> for each row. When an image has no padding, it will use its 184lightweight horizontal iterator (as opposed to the more complex 1D image 185iterator that has to check for the end of rows). It choses the fastest method, 186taking into account both static and run-time parameters.</p> 187</div> 188<div class="section" id="histogram"> 189<h2><a class="toc-backref" href="#id3">Histogram</a></h2> 190<p>The histogram can be computed by counting the number of pixel values that fall 191in each bin. The following method takes a grayscale (one-dimensional) image 192view, since only grayscale pixels are convertible to integers:</p> 193<div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">GrayView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">R</span><span class="o">></span> 194<span class="kt">void</span> <span class="n">grayimage_histogram</span><span class="p">(</span><span class="k">const</span> <span class="n">GrayView</span><span class="o">&</span> <span class="n">img</span><span class="p">,</span> <span class="n">R</span><span class="o">&</span> <span class="n">hist</span><span class="p">)</span> 195<span class="p">{</span> 196 <span class="k">for</span> <span class="p">(</span><span class="k">typename</span> <span class="n">GrayView</span><span class="o">::</span><span class="n">iterator</span> <span class="n">it</span><span class="o">=</span><span class="n">img</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span> <span class="n">it</span><span class="o">!=</span><span class="n">img</span><span class="p">.</span><span class="n">end</span><span class="p">();</span> <span class="o">++</span><span class="n">it</span><span class="p">)</span> 197 <span class="o">++</span><span class="n">hist</span><span class="p">[</span><span class="o">*</span><span class="n">it</span><span class="p">];</span> 198<span class="p">}</span> 199</pre></div> 200</div> 201<p>Using <code class="docutils literal"><span class="pre">boost::lambda</span></code> and GIL’s <code class="docutils literal"><span class="pre">for_each_pixel</span></code> algorithm, we can write 202this more compactly:</p> 203<div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">GrayView</span><span class="p">,</span> <span class="k">typename</span> <span class="n">R</span><span class="o">></span> 204<span class="kt">void</span> <span class="n">grayimage_histogram</span><span class="p">(</span><span class="k">const</span> <span class="n">GrayView</span><span class="o">&</span> <span class="n">v</span><span class="p">,</span> <span class="n">R</span><span class="o">&</span> <span class="n">hist</span><span class="p">)</span> 205<span class="p">{</span> 206 <span class="n">for_each_pixel</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="o">++</span><span class="n">var</span><span class="p">(</span><span class="n">hist</span><span class="p">)[</span><span class="n">_1</span><span class="p">]);</span> 207<span class="p">}</span> 208</pre></div> 209</div> 210<p>Where <code class="docutils literal"><span class="pre">for_each_pixel</span></code> invokes <code class="docutils literal"><span class="pre">std::for_each</span></code> and <code class="docutils literal"><span class="pre">var</span></code> and <code class="docutils literal"><span class="pre">_1</span></code> are 211<code class="docutils literal"><span class="pre">boost::lambda</span></code> constructs. To compute the luminosity histogram, we call the 212above method using the grayscale view of an image:</p> 213<div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">View</span><span class="p">,</span> <span class="k">typename</span> <span class="n">R</span><span class="o">></span> 214<span class="kt">void</span> <span class="n">luminosity_histogram</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&</span> <span class="n">v</span><span class="p">,</span> <span class="n">R</span><span class="o">&</span> <span class="n">hist</span><span class="p">)</span> 215<span class="p">{</span> 216 <span class="n">grayimage_histogram</span><span class="p">(</span><span class="n">color_converted_view</span><span class="o"><</span><span class="n">gray8_pixel_t</span><span class="o">></span><span class="p">(</span><span class="n">v</span><span class="p">),</span><span class="n">hist</span><span class="p">);</span> 217<span class="p">}</span> 218</pre></div> 219</div> 220<p>This is how to invoke it:</p> 221<div class="highlight-cpp"><div class="highlight"><pre><span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">hist</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span> 222<span class="n">std</span><span class="o">::</span><span class="n">fill</span><span class="p">(</span><span class="n">hist</span><span class="p">,</span><span class="n">hist</span><span class="o">+</span><span class="mi">256</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span> 223<span class="n">luminosity_histogram</span><span class="p">(</span><span class="n">my_view</span><span class="p">,</span><span class="n">hist</span><span class="p">);</span> 224</pre></div> 225</div> 226<p>If we want to view the histogram of the second channel of the image in the top 227left 100x100 area, we call:</p> 228<div class="highlight-cpp"><div class="highlight"><pre><span class="n">grayimage_histogram</span><span class="p">(</span><span class="n">nth_channel_view</span><span class="p">(</span><span class="n">subimage_view</span><span class="p">(</span><span class="n">img</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">100</span><span class="p">,</span><span class="mi">100</span><span class="p">),</span><span class="mi">1</span><span class="p">),</span><span class="n">hist</span><span class="p">);</span> 229</pre></div> 230</div> 231<p>No pixels are copied and no extra memory is allocated - the code operates 232directly on the source pixels, which could be in any supported color space and 233channel depth. They could be either planar or interleaved.</p> 234</div> 235<div class="section" id="using-image-views"> 236<h2><a class="toc-backref" href="#id4">Using image views</a></h2> 237<p>The following code illustrates the power of using image views:</p> 238<div class="highlight-cpp"><div class="highlight"><pre><span class="n">jpeg_read_image</span><span class="p">(</span><span class="s">"monkey.jpg"</span><span class="p">,</span> <span class="n">img</span><span class="p">);</span> 239<span class="n">step1</span><span class="o">=</span><span class="n">view</span><span class="p">(</span><span class="n">img</span><span class="p">);</span> 240<span class="n">step2</span><span class="o">=</span><span class="n">subimage_view</span><span class="p">(</span><span class="n">step1</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span><span class="mi">300</span><span class="p">,</span> <span class="mi">150</span><span class="p">,</span><span class="mi">150</span><span class="p">);</span> 241<span class="n">step3</span><span class="o">=</span><span class="n">color_converted_view</span><span class="o"><</span><span class="n">rgb8_view_t</span><span class="p">,</span><span class="n">gray8_pixel_t</span><span class="o">></span><span class="p">(</span><span class="n">step2</span><span class="p">);</span> 242<span class="n">step4</span><span class="o">=</span><span class="n">rotated180_view</span><span class="p">(</span><span class="n">step3</span><span class="p">);</span> 243<span class="n">step5</span><span class="o">=</span><span class="n">subsampled_view</span><span class="p">(</span><span class="n">step4</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span> 244<span class="n">jpeg_write_view</span><span class="p">(</span><span class="s">"monkey_transform.jpg"</span><span class="p">,</span> <span class="n">step5</span><span class="p">);</span> 245</pre></div> 246</div> 247<p>The intermediate images are shown here:</p> 248<img alt="../_images/monkey_steps.jpg" src="../_images/monkey_steps.jpg" /> 249<p>Notice that no pixels are ever copied. All the work is done inside 250<code class="docutils literal"><span class="pre">jpeg_write_view</span></code>. If we call our <code class="docutils literal"><span class="pre">luminosity_histogram</span></code> with 251<code class="docutils literal"><span class="pre">step5</span></code> it will do the right thing.</p> 252</div> 253</div> 254 255 256 <div class="navbar" style="text-align:right;"> 257 258 259 <a class="prev" title="Metafunctions" href="metafunctions.html"><img src="../_static/prev.png" alt="prev"/></a> 260 <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a> 261 <a class="next" title="Technicalities" href="technicalities.html"><img src="../_static/next.png" alt="next"/></a> 262 263 </div> 264 </div> 265 <div class="footer" role="contentinfo"> 266 Last updated on 2020-08-11 15:08:48. 267 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6. 268 </div> 269 </body> 270</html>