??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久精品久久久久久,久久久91精品国产一区二区三区,99久久免费国产特黄http://cppblog.com/Shihira/category/19614.htmlOpen source - 开放源代码 - 開放原始?- オープンソー?- 오픈 소스 - От{орен aо - متن‌با?/description>zh-cnWed, 12 Aug 2015 01:20:42 GMTWed, 12 Aug 2015 01:20:42 GMT60L与^滑o波器的图像处理应?/title><link>http://m.shnenglu.com/Shihira/archive/2015/08/12/211542.html</link><dc:creator>Shihira</dc:creator><author>Shihira</author><pubDate>Tue, 11 Aug 2015 16:35:00 GMT</pubDate><guid>http://m.shnenglu.com/Shihira/archive/2015/08/12/211542.html</guid><wfw:comment>http://m.shnenglu.com/Shihira/comments/211542.html</wfw:comment><comments>http://m.shnenglu.com/Shihira/archive/2015/08/12/211542.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/Shihira/comments/commentRss/211542.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/Shihira/services/trackbacks/211542.html</trackback:ping><description><![CDATA[<div><div><h1>L的介l?/h1> <p>L<em>QconvolutionQ?/em>是泛函分析里的一个概念,不过泛函分析一般都是数学系才学的,计算机系的学生大多在概率l计课本里了解到。它分ؓ两种形式Q一个是L形式Q一个是q箋Q积分)形式。在囑փ处理中我们更兛_LLQ不q也先看看积分Ş式的L。现在假设我们有两个函数<img src="http://latex.codecogs.com/gif.latex?f%28x%29" alt="f(x)" />?img src="http://latex.codecogs.com/gif.latex?g%28x%29" alt="g(x)" />Q这?img src="http://latex.codecogs.com/gif.latex?g%28x%29" alt="g(x)" />又叫?strong>qx函数</strong>或?strong>L?/strong>Q那么它们在q箋I间的卷U是Q?/p> <img src="http://latex.codecogs.com/gif.latex?%28f*g%29%28x%29=%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28t%29g%28x-t%29dt" alt="(f*g)(x)=\int_{-\infty}^{\infty}f(t)g(x-t)dt" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <p>一般我们有一个这Ll论Q就是当<img src="http://latex.codecogs.com/gif.latex?f%28x%29" alt="f(x)" />l过_多次相同qx函数<img src="http://latex.codecogs.com/gif.latex?g%28x%29" alt="g(x)" />LQ就会够接q高斯函敎ͼ也就是正态分布的函数形式。卷U就是一U^滑操作,q说明高斯函数就?#8220;最qx的函?#8221;。引入热力学中熵的概念,高斯函数是拥有最高熵的函敎ͼ最E_的状态,以至于自然界大多数的l计规律都呈现出正态分布:</p> <img src="http://latex.codecogs.com/gif.latex?%28%28%5Ccdots%28%28f*g%29*g%29%5Ccdots%29*g%29%28x%29%20%5Crightarrow%20%5Cfrac%201%7B%5Csigma%5Csqrt%7B2%5Cpi%7D%7D%20e%5E%7B-x%5E2/%7B%5Csigma%5E2%7D%7D" alt="((\cdots((f*g)*g)\cdots)*g)(x) \rightarrow \frac 1{\sigma\sqrt{2\pi}} e^{-x^2/{\sigma^2}}" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <p>下面介绍L形式的卷U。这LQ首先是由有限项的多式体现。神奇的是,而它们的乘积是L。首先我们设有两个多式<img src="http://latex.codecogs.com/gif.latex?p%20=%20a_0%20+%20a_1%20x%20+%20a_2%20x%5E2" alt="p = a_0 + a_1 x + a_2 x^2" />以及<img src="http://latex.codecogs.com/gif.latex?q%20=%20b_0%20+%20b_1%20x%20+%20b_2%20x%5E2%20+%20b_3%20x%5E3" alt="q = b_0 + b_1 x + b_2 x^2 + b_3 x^3" />。计它们的乘积Q?/p> <img src="http://latex.codecogs.com/gif.latex?%5Cbegin%7Balign*%7D%0Ar%20=%20p%5Ccdot%20q%20&=%20%28a_0%20b_0%29%20%5C%5C%0A&+%20%28a_0%20b_1%20+%20a_1%20b_0%29%20x%20%5C%5C%0A&+%20%28a_0%20b_2%20+%20a_1%20b_1+%20a_2%20b_0%29%20x%5E2%20%5C%5C%0A&+%20%28a_0%20b_3%20+%20a_1%20b_2%20+%20a_2%20b_1%29%20x%5E3%20%5C%5C%0A&+%20%28a_1%20b_3%20+%20a_2%20b_2%29%20x%5E4%20%5C%5C%0A&+%20%28a_2%20b_3%29%20x%5E5%0A%5Cend%7Balign*%7D" alt="\begin{align*} r = p\cdot q &= (a_0 b_0) \\ &+ (a_0 b_1 + a_1 b_0) x \\ &+ (a_0 b_2 + a_1 b_1+ a_2 b_0) x^2 \\ &+ (a_0 b_3 + a_1 b_2 + a_2 b_1) x^3 \\ &+ (a_1 b_3 + a_2 b_2) x^4 \\ &+ (a_2 b_3) x^5 \end{align*}" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <p>再引入离散Ş式卷U(向量LQ的定义Q大家比较一下这个定义和上面多项式的计算。稍微说明一下,中括L意义?strong>p[n]代表向量Wn个元?/strong>。将两个多项式的pL写成向量形式然后q行向量LQ也是例如<img src="http://latex.codecogs.com/gif.latex?p%20=%20%5Ba_0,%20a_1,%20a_2%5D" alt="p = [a_0, a_1, a_2]" />Q而没定义的地方当?。可以发玎ͼ两者是完全一致的Q?/p> <img src="http://latex.codecogs.com/gif.latex?%5Cbegin%7Balign*%7D%0A%28p%20*%20q%29%5Bn%5D%20&=%20%5Csum_%7Bm=-%5Cinfty%7D%5E%5Cinfty%20p%5Bm%5D%5Ccdot%20q%5Bn-m%5D%20%5C%5C%0Ar%5B1%5D%20&=%20%5Csum_%7Bm=0%7D%5E1%20%20p%5Bm%5D%5Ccdot%20q%5B1-m%5D%20&&=%20a_0%20b_1%20+%20a_1%20b_0%20%5C%5C%0Ar%5B2%5D%20&=%20%5Csum_%7Bm=0%7D%5E2%20%20p%5Bm%5D%5Ccdot%20q%5B2-m%5D%20&&=%20a_0%20b_2%20+%20a_1%20b_1%20+%20a_2%20b_0%20%5C%5C%0A&%5Ccdots%0A%5Cend%7Balign*%7D" alt="\begin{align*} (p * q)[n] &= \sum_{m=-\infty}^\infty p[m]\cdot q[n-m] \\ r[1] &= \sum_{m=0}^1 p[m]\cdot q[1-m] &&= a_0 b_1 + a_1 b_0 \\ r[2] &= \sum_{m=0}^2 p[m]\cdot q[2-m] &&= a_0 b_2 + a_1 b_1 + a_2 b_0 \\ &\cdots \end{align*}" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <blockquote><p>知道了多式的乘U就是其相应的卷U,我们甚至可以直接得出两个q数卷U的l果。因为泰勒数就是幂U数的一U,所以我们可以将几乎所有的q箋函数转换成离散Ş式,避免了繁复的U分q算Q比如我们希望得?<img src="http://latex.codecogs.com/gif.latex?r%28x%29%20=%20p%28x%29%20*%20q%28x%29" alt="r(x) = p(x) * q(x)" />Q其?img src="http://latex.codecogs.com/gif.latex?p%28x%29%20=%20%5Csum%20a_i%20x%5Ei,%5C%20%20q%28x%29%20=%20%5Csum%20b_i%20x%5Ei" alt="p(x) = \sum a_i x^i,\ q(x) = \sum b_i x^i" />Q只需要简单地计算q两个数的<strong>柯西乘积</strong>Q所得结果就?img src="http://latex.codecogs.com/gif.latex?r%28x%29" alt="r(x)" />的卷U。当然了Q这是后话,与本文的主题无关?/p></blockquote> <h1>L与图像处?/h1> <p>在开始讲囑փ处理之前Q我希望先理解一下卷U的整个q程是怎样的。从上面的公式看得还是有Ҏ應|懂,从直觉上ȝ解一下很有必要。观察卷U的公式以及下面的图片,q个q程可以看作Q当你想求一个r[n]的时候:</p> <blockquote><p>你先把卷U核q叠在p上面Q?strong>量</strong>使左端靠q(如果左对齐就再好不过了)Q然后看看在<strong>[0, n]?/strong>p, q重叠的部分是从哪里到哪里Q分别写成向量,那么r[n]q于其中一个向量与另一个向量的<strong>逆序</strong>的内U?/p></blockquote> <p>比如当n = 2Ӟ两个向量?code>[a_0, a_1, a_2]</code>?code>[b_2, b_1, b_0]</code>Qn = 4Ӟ两个向量?code>[a_1, a_2, a_3, a_4]</code>?code>[b_3, b_2, b_1, b_0]</code>。至于求内积Q一定难不倒你。下图说明了q一点:</p> <img src="http://latex.codecogs.com/gif.latex?%5Cbegin%7Balign*%7D%0A&&%20a_0%20%20%20%20&&%20a_1%20%20%20%20&&%20a_2%20%20%20%20&&%20a_3%20%20%20%20&&%20a_4%20%5C%5C%0A&&%20a_0b_0%20&&%20a_0b_1%20&&%20a_0b_2%20&&%20a_0b_3%20%5C%5C%0A&&%20%20%20%20%20%20%20%20&&%20a_1b_0%20&&%20a_1b_1%20&&%20a_1b_2%20&&%20a_1b_3%20%5C%5C%0A&&%20%20%20%20%20%20%20%20&&%20%20%20%20%20%20%20%20&&%20a_2b_0%20&&%20a_2b_1%20&&%20a_2b_2%20&&%20a_2b_3%20%5C%5C%0A&&%20%20%20%20%20%20%20%20&&%20%20%20%20%20%20%20%20&&%20%20%20%20%20%20%20%20&&%20a_3b_0%20&&%20a_3b_1%20&&%20a_3b_2%20&&%20a_3b_3%20%5C%5C%0A&&%20%20%20%20%20%20%20%20&&%20%20%20%20%20%20%20%20&&%20%20%20%20%20%20%20%20&&%20%20%20%20%20%20%20%20&&%20a_4b_0%20&&%20a_4b_1%20&&%20a_4b_2%20&&%20a_4b_3%20%5C%5C%0A%5Chline%0A&&%20c_0%20%20%20%20&&%20c_1%20%20%20%20&&%20c_2%20%20%20%20&&%20c_3%20%20%20%20&&%20c_4%20%20%20%20&&%20c_5%20%20%20%20&&%20c_6%20%20%20%20&&%20c_7%0A%5Cend%7Balign*%7D" alt="\begin{align*} && a_0 && a_1 && a_2 && a_3 && a_4 \\ && a_0b_0 && a_0b_1 && a_0b_2 && a_0b_3 \\ && && a_1b_0 && a_1b_1 && a_1b_2 && a_1b_3 \\ && && && a_2b_0 && a_2b_1 && a_2b_2 && a_2b_3 \\ && && && && a_3b_0 && a_3b_1 && a_3b_2 && a_3b_3 \\ && && && && && a_4b_0 && a_4b_1 && a_4b_2 && a_4b_3 \\ \hline && c_0 && c_1 && c_2 && c_3 && c_4 && c_5 && c_6 && c_7 \end{align*}" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <p>上面是对某一点上L的理解。对整个域的LQ则可以看成是将L核(除了开头几个外Q不停向右移动,每移动一格就重叠部分拿出来求内U?/p> <p>q时我们可以把图像处理和L联系h了。图像处理是Q将一?#8220;源图?#8221;<em>QSourceQ?/em>Q通过一些算法,变成一?#8220;目标囑փ”<em>QDestinationQ?/em>。当我们q行qx处理的时候,用到一个叫做o波器<em>QfilterQ?/em>?东西Q也叫做滤镜。想x们现实生zM攑֤镜是怎么用的Q拿着攑֤镜,从报U的左上角开始,一直扫啊扫到右下角Q扫的过E中一直望着攑֤镜和报纸的重叠区 域(其实是望着攑֤镜,因ؓ它比报纸多了)Q这样你浏览完了一张放大过的报U。^滑o镜也是同L使用ҎQ从源图的左上角开始扫到右下角Q扫的过 E中一直取出重叠部分进?strong>内积</strong>计算Q然后将l果存放到目标图像中 —— 昄q个操作跟卷U是一致的Q只不过定义在二l空间内?/p> <p>Z方便量化表示Q我们把囑փ抽象成定义在<img src="http://latex.codecogs.com/gif.latex?R%20%5Ccap%20%5B0,%201%5D" alt="R \cap [0, 1]" /> 数环内的二维矩阵Q其意义?strong>灰度?/strong>Q颜色信息我们暂且忽略。卷U核Q也是滤L器同样也是定义在<img src="http://latex.codecogs.com/gif.latex?R%20%5Ccap%20%5B0,%201%5D" alt="R \cap [0, 1]" /> 内的二维矩阵。这P二维的卷U我们这样定义它的离散Ş式:</p> <img src="http://latex.codecogs.com/gif.latex?%5Ctext%7BDest%7D%5Bi,%20j%5D%20=%20%5Csum_%7By=-%5Cinfty%7D%5E%5Cinfty%20%5Csum_%7Bx=-%5Cinfty%7D%5E%5Cinfty%20%5Ctext%7BSrc%7D%5By,x%5D%20%5Ccdot%20%5Ctext%7BKer%7D%5Bi%20-%20y,%20j%20-%20x%5D" alt="\text{Dest}[i, j] = \sum_{y=-\infty}^\infty \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}[i - y, j - x]" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <p>我们的卷U核大小q不是无限的Q它一个半径rQ这样它的大就?r+1。规定了q个r使得Q当|x| > r ?|y| > rQ都有Ker[y, x] = 0。规定过大小之后Q由 <code>|i-y| < r; |j-x| < r</code>得到 <strong><code>i-r < y < i+r; j-r < x < j+r</code></strong>。同时我们规定Dest和Src的大是<img src="http://latex.codecogs.com/gif.latex?m%20%5Ctimes%20n" alt="m \times n" />。于是我们得C滤L器的法Q?/p> <img src="http://latex.codecogs.com/gif.latex?%5Ctext%7BDest%7D%5Bi,%20j%5D%20=%20%5Csum_%7By=%5Cmax%5C%7B0,i-r%5C%7D%7D%5E%7B%5Cmin%5C%7Bi+r,n%5C%7D%7D%20%5Cleft%28%20%5Csum_%7Bx=%5Cmax%5C%7B0,j-r%5C%7D%7D%5E%7B%5Cmin%5C%7Bj+r,m%5C%7D%7D%20%5Ctext%7BSrc%7D%5By,%20x%5D%20%5Ccdot%20%5Ctext%7BKer%7D%5Bi%20-%20y,%20j%20-%20x%5D%20%5Cright%29" alt="\text{Dest}[i, j] = \sum_{y=\max\{0,i-r\}}^{\min\{i+r,n\}} \left( \sum_{x=\max\{0,j-r\}}^{\min\{j+r,m\}} \text{Src}[y, x] \cdot \text{Ker}[i - y, j - x] \right)" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <h1>高斯滤L?/h1> <div imagebubble"=""> <img src="http://upload-images.jianshu.io/upload_images/610338-54f1c66e805cdc4c.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="二维的高斯函敎ͼ俗称避孕套函敎ͼ" data-original-src="http://upload-images.jianshu.io/upload_images/610338-54f1c66e805cdc4c.gif" /><br /><div>二维的高斯函敎ͼ俗称避孕套函敎ͼ</div> </div> <p>高斯滤L器是最常用的^滑o波器之一Q在Photoshop里面它被用作<strong>高斯模糊滤镜</strong>。高斯o波器的定义很l典Q就是简单地把正态分布离散开来。二lŞ式只是单U把x替代?x<sup>2</sup> + y<sup>2</sup>)Q然后修改系Co实数域上的积分ؓ1Q?/p> <img src="http://latex.codecogs.com/gif.latex?%5Cbegin%7Balign*%7D%0A%5Ctext%7BKer%7D_1%5Bx%5D%20&=%20%5Cfrac%201%7B%5Csigma%5Csqrt%7B2%5Cpi%7D%7D%20e%5E%7B-x%5E2/%7B%5Csigma%5E2%7D%7D%20%5C%5C%0A%5Ctext%7BKer%7D_2%5Bi,%20j%5D%20&=%20%5Cfrac%201%7B2%5Csigma%5E2%5Cpi%7D%20e%5E%7B-%28i%5E2+j%5E2%29/%7B%5Csigma%5E2%7D%7D%0A%5Cend%7Balign*%7D" alt="\begin{align*} \text{Ker}_1[x] &= \frac 1{\sigma\sqrt{2\pi}} e^{-x^2/{\sigma^2}} \\ \text{Ker}_2[i, j] &= \frac 1{2\sigma^2\pi} e^{-(i^2+j^2)/{\sigma^2}} \end{align*}" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <p>也许你已l发C一个这L规律Q这一规律Q这在更高维上仍然是满的,也就是在q箋I间里同h뀂这成为我们优化算法的关键。将q个规律代回Cl离散卷U的公式里,因ؓy在第二个q加中相当于常数pL可以提出来,我们发现Q?/p> <img src="http://latex.codecogs.com/gif.latex?%5Cbegin%7Balign*%7D%0A%5Ctext%7BKer%7D_2%5Bi,%20j%5D%20&=%20%5Ctext%7BKer%7D_1%5Bi%5D%20%5Ccdot%20%5Ctext%7BKer%7D_1%5Bj%5D%20%5C%5C%0A%5Ctext%7BDest%7D%5Bi,%20j%5D%20&=%20%5Csum_%7By=-%5Cinfty%7D%5E%5Cinfty%20%5Csum_%7Bx=-%5Cinfty%7D%5E%5Cinfty%20%5Ctext%7BSrc%7D%5By,x%5D%20%5Ccdot%20%5Ctext%7BKer%7D_2%5Bi%20-%20y,%20j%20-%20x%5D%20%5C%5C%0A&=%20%5Csum_%7By=-%5Cinfty%7D%5E%5Cinfty%20%5Csum_%7Bx=-%5Cinfty%7D%5E%5Cinfty%20%5Ctext%7BSrc%7D%5By,x%5D%20%5Ccdot%20%5Ctext%7BKer%7D_1%5Bi-y%5D%20%5Ccdot%20%5Ctext%7BKer%7D_1%5Bj-x%5D%5C%5C%0A&=%20%5Csum_%7By=-%5Cinfty%7D%5E%5Cinfty%20%5Cleft%28%20%5Csum_%7Bx=-%5Cinfty%7D%5E%5Cinfty%20%5Ctext%7BSrc%7D%5By,x%5D%20%5Ccdot%20%5Ctext%7BKer%7D_1%5Bj-x%5D%5Cright%29%20%5Ctext%7BKer%7D_1%5Bi-y%5D%0A%5Cend%7Balign*%7D" alt="\begin{align*} \text{Ker}_2[i, j] &= \text{Ker}_1[i] \cdot \text{Ker}_1[j] \\ \text{Dest}[i, j] &= \sum_{y=-\infty}^\infty \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}_2[i - y, j - x] \\ &= \sum_{y=-\infty}^\infty \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}_1[i-y] \cdot \text{Ker}_1[j-x]\\ &= \sum_{y=-\infty}^\infty \left( \sum_{x=-\infty}^\infty \text{Src}[y,x] \cdot \text{Ker}_1[j-x]\right) \text{Ker}_1[i-y] \end{align*}" style="display: block; margin: 20px; margin-left: auto; margin-right: auto;" /> <p>如果xq加所表示是卷U是从右上角开始按照文字书写顺序从左到叻I然后从上C的顺序进行一l卷U,那么yq加表示的卷U就是先从上CQ再从左到有的顺序卷U。在OpenCV提供的数据结构的基础上,不用imgproc提供的算法,我写了一个示例:</p><p><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span> <span style="color: #008000; ">//</span><span style="color: #008000; "> cflags: -lopencv_highgui -lopencv_core</span><span style="color: #008000; "><br /></span><span style="color: #008080; "> 2</span> <span style="color: #008000; "></span><span style="color: #000000; "><br /></span><span style="color: #008080; "> 3</span> <span style="color: #000000; ">#include </span><span style="color: #000000; "><</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">></span><span style="color: #000000; "><br /></span><span style="color: #008080; "> 4</span> <span style="color: #000000; ">#include </span><span style="color: #000000; "><</span><span style="color: #000000; ">cmath</span><span style="color: #000000; ">></span><span style="color: #000000; "><br /></span><span style="color: #008080; "> 5</span> <span style="color: #000000; ">#include </span><span style="color: #000000; "><</span><span style="color: #000000; ">opencv2</span><span style="color: #000000; ">/</span><span style="color: #000000; ">highgui</span><span style="color: #000000; ">/</span><span style="color: #000000; ">highgui.hpp</span><span style="color: #000000; ">></span><span style="color: #000000; "><br /></span><span style="color: #008080; "> 6</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 7</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; "> cv;<br /></span><span style="color: #008080; "> 8</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; "> std;<br /></span><span style="color: #008080; "> 9</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">10</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">const</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; "> title </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">gaussian-filter</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">11</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">12</span> <span style="color: #000000; ">Mat kernelMatrix(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> radius, </span><span style="color: #0000FF; ">double</span><span style="color: #000000; "> sigma)<br /></span><span style="color: #008080; ">13</span> <span style="color: #000000; ">{<br /></span><span style="color: #008080; ">14</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> d </span><span style="color: #000000; ">=</span><span style="color: #000000; "> radius </span><span style="color: #000000; ">*</span><span style="color: #000000; "> </span><span style="color: #000000; ">2</span><span style="color: #000000; "> </span><span style="color: #000000; ">+</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">15</span> <span style="color: #000000; ">        Mat kernel(</span><span style="color: #000000; ">2</span><span style="color: #000000; ">, d, CV_64F);<br /></span><span style="color: #008080; ">16</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">17</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">double</span><span style="color: #000000; "> coef </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">18</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> i </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">; i </span><span style="color: #000000; "><=</span><span style="color: #000000; "> radius; i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">) {<br /></span><span style="color: #008080; ">19</span> <span style="color: #000000; ">                </span><span style="color: #008000; ">//</span><span style="color: #008000; "> f(x) = 1/(sigma * sqrt(2 pi)) * e ^ -x^2/(2 s^2)</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">20</span> <span style="color: #008000; "></span><span style="color: #000000; ">                </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> dx </span><span style="color: #000000; ">=</span><span style="color: #000000; "> i </span><span style="color: #000000; ">-</span><span style="color: #000000; "> radius;<br /></span><span style="color: #008080; ">21</span> <span style="color: #000000; ">                </span><span style="color: #0000FF; ">double</span><span style="color: #000000; "> dx_2 </span><span style="color: #000000; ">=</span><span style="color: #000000; "> dx </span><span style="color: #000000; ">*</span><span style="color: #000000; "> dx;<br /></span><span style="color: #008080; ">22</span> <span style="color: #000000; ">                </span><span style="color: #0000FF; ">double</span><span style="color: #000000; "> w </span><span style="color: #000000; ">=</span><span style="color: #000000; "> pow(M_E, </span><span style="color: #000000; ">-</span><span style="color: #000000; "> dx_2 </span><span style="color: #000000; ">/</span><span style="color: #000000; "> (</span><span style="color: #000000; ">2</span><span style="color: #000000; "> </span><span style="color: #000000; ">*</span><span style="color: #000000; "> sigma </span><span style="color: #000000; ">*</span><span style="color: #000000; "> sigma));<br /></span><span style="color: #008080; ">23</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">24</span> <span style="color: #000000; ">                coef </span><span style="color: #000000; ">+=</span><span style="color: #000000; "> w;<br /></span><span style="color: #008080; ">25</span> <span style="color: #000000; ">                kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">, i) </span><span style="color: #000000; ">=</span><span style="color: #000000; "> w;<br /></span><span style="color: #008080; ">26</span> <span style="color: #000000; ">                kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">, d </span><span style="color: #000000; ">-</span><span style="color: #000000; "> i </span><span style="color: #000000; ">-</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">) </span><span style="color: #000000; ">=</span><span style="color: #000000; "> w;<br /></span><span style="color: #008080; ">27</span> <span style="color: #000000; ">                </span><span style="color: #008000; ">//</span><span style="color: #008000; "> when you used values from i to j (j>i), the sum of them is:<br /></span><span style="color: #008080; ">28</span> <span style="color: #008000; ">                </span><span style="color: #008000; ">//</span><span style="color: #008000; "> kernel[1, j] - (i ? kernel[1, i-1] : 0)</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">29</span> <span style="color: #008000; "></span><span style="color: #000000; ">                kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">, i) </span><span style="color: #000000; ">=</span><span style="color: #000000; "> coef;<br /></span><span style="color: #008080; ">30</span> <span style="color: #000000; ">        }<br /></span><span style="color: #008080; ">31</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">32</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> i </span><span style="color: #000000; ">=</span><span style="color: #000000; "> radius </span><span style="color: #000000; ">+</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">; i </span><span style="color: #000000; "><</span><span style="color: #000000; "> d; i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">) {<br /></span><span style="color: #008080; ">33</span> <span style="color: #000000; ">                coef </span><span style="color: #000000; ">+=</span><span style="color: #000000; "> kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">, i);<br /></span><span style="color: #008080; ">34</span> <span style="color: #000000; ">                kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">, i) </span><span style="color: #000000; ">=</span><span style="color: #000000; "> coef;<br /></span><span style="color: #008080; ">35</span> <span style="color: #000000; ">        }<br /></span><span style="color: #008080; ">36</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">37</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> kernel;<br /></span><span style="color: #008080; ">38</span> <span style="color: #000000; ">}<br /></span><span style="color: #008080; ">39</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">40</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">41</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> convolution(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; "> Mat</span><span style="color: #000000; ">&</span><span style="color: #000000; "> img, </span><span style="color: #0000FF; ">const</span><span style="color: #000000; "> Mat</span><span style="color: #000000; ">&</span><span style="color: #000000; "> kernel, Mat</span><span style="color: #000000; ">&</span><span style="color: #000000; "> output, </span><span style="color: #0000FF; ">bool</span><span style="color: #000000; "> t </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">42</span> <span style="color: #000000; ">{<br /></span><span style="color: #008080; ">43</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> y </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">, x </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">; y </span><span style="color: #000000; "><</span><span style="color: #000000; "> img.rows; x </span><span style="color: #000000; ">=</span><span style="color: #000000; "> (</span><span style="color: #000000; ">++</span><span style="color: #000000; ">x</span><span style="color: #000000; "><</span><span style="color: #000000; ">img.cols)</span><span style="color: #000000; ">?</span><span style="color: #000000; "> x : (y</span><span style="color: #000000; ">++</span><span style="color: #000000; ">, </span><span style="color: #000000; ">0</span><span style="color: #000000; ">)) {<br /></span><span style="color: #008080; ">44</span> <span style="color: #000000; ">                Vec3d r(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">, </span><span style="color: #000000; ">0</span><span style="color: #000000; ">, </span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">45</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">46</span> <span style="color: #000000; ">                </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> ideal </span><span style="color: #000000; ">=</span><span style="color: #000000; "> x </span><span style="color: #000000; ">-</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">(kernel.cols </span><span style="color: #000000; ">/</span><span style="color: #000000; "> </span><span style="color: #000000; ">2</span><span style="color: #000000; ">),<br /></span><span style="color: #008080; ">47</span> <span style="color: #000000; ">                    ran_beg </span><span style="color: #000000; ">=</span><span style="color: #000000; "> max(ideal, </span><span style="color: #000000; ">0</span><span style="color: #000000; ">) </span><span style="color: #000000; ">-</span><span style="color: #000000; "> ideal,<br /></span><span style="color: #008080; ">48</span> <span style="color: #000000; ">                    ran_end </span><span style="color: #000000; ">=</span><span style="color: #000000; "> min(ideal </span><span style="color: #000000; ">+</span><span style="color: #000000; "> kernel.cols, img.cols) </span><span style="color: #000000; ">-</span><span style="color: #000000; "> ideal;<br /></span><span style="color: #008080; ">49</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">50</span> <span style="color: #000000; ">                </span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> i </span><span style="color: #000000; ">=</span><span style="color: #000000; "> ran_beg; i </span><span style="color: #000000; "><</span><span style="color: #000000; "> ran_end; i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">) {<br /></span><span style="color: #008080; ">51</span> <span style="color: #000000; ">                        </span><span style="color: #0000FF; ">double</span><span style="color: #000000; "> weight </span><span style="color: #000000; ">=</span><span style="color: #000000; "> kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">, i);<br /></span><span style="color: #008080; ">52</span> <span style="color: #000000; ">                        Vec3b pixel </span><span style="color: #000000; ">=</span><span style="color: #000000; "> img.at</span><span style="color: #000000; "><</span><span style="color: #000000; ">Vec3b</span><span style="color: #000000; ">></span><span style="color: #000000; ">(y, ideal </span><span style="color: #000000; ">+</span><span style="color: #000000; "> i);<br /></span><span style="color: #008080; ">53</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">54</span> <span style="color: #000000; ">                        r[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">] </span><span style="color: #000000; ">+=</span><span style="color: #000000; "> pixel[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">] </span><span style="color: #000000; ">*</span><span style="color: #000000; "> weight;<br /></span><span style="color: #008080; ">55</span> <span style="color: #000000; ">                        r[</span><span style="color: #000000; ">1</span><span style="color: #000000; ">] </span><span style="color: #000000; ">+=</span><span style="color: #000000; "> pixel[</span><span style="color: #000000; ">1</span><span style="color: #000000; ">] </span><span style="color: #000000; ">*</span><span style="color: #000000; "> weight;<br /></span><span style="color: #008080; ">56</span> <span style="color: #000000; ">                        r[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">] </span><span style="color: #000000; ">+=</span><span style="color: #000000; "> pixel[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">] </span><span style="color: #000000; ">*</span><span style="color: #000000; "> weight;<br /></span><span style="color: #008080; ">57</span> <span style="color: #000000; ">                }<br /></span><span style="color: #008080; ">58</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">59</span> <span style="color: #000000; ">                </span><span style="color: #0000FF; ">double</span><span style="color: #000000; "> coef </span><span style="color: #000000; ">=</span><span style="color: #000000; "> kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">, ran_end </span><span style="color: #000000; ">-</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">60</span> <span style="color: #000000; ">                </span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(ran_beg) coef </span><span style="color: #000000; ">-=</span><span style="color: #000000; "> kernel.at</span><span style="color: #000000; "><</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">></span><span style="color: #000000; ">(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">, ran_beg </span><span style="color: #000000; ">-</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">61</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">62</span> <span style="color: #000000; ">                output.at</span><span style="color: #000000; "><</span><span style="color: #000000; ">Vec3b</span><span style="color: #000000; ">></span><span style="color: #000000; ">(t</span><span style="color: #000000; ">?</span><span style="color: #000000; ">x:y, t</span><span style="color: #000000; ">?</span><span style="color: #000000; ">y:x) </span><span style="color: #000000; ">=</span><span style="color: #000000; "> Vec3b(<br /></span><span style="color: #008080; ">63</span> <span style="color: #000000; ">                        saturate_cast</span><span style="color: #000000; "><</span><span style="color: #000000; ">uchar</span><span style="color: #000000; ">></span><span style="color: #000000; ">(r[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">]</span><span style="color: #000000; ">/</span><span style="color: #000000; ">coef),<br /></span><span style="color: #008080; ">64</span> <span style="color: #000000; ">                        saturate_cast</span><span style="color: #000000; "><</span><span style="color: #000000; ">uchar</span><span style="color: #000000; ">></span><span style="color: #000000; ">(r[</span><span style="color: #000000; ">1</span><span style="color: #000000; ">]</span><span style="color: #000000; ">/</span><span style="color: #000000; ">coef),<br /></span><span style="color: #008080; ">65</span> <span style="color: #000000; ">                        saturate_cast</span><span style="color: #000000; "><</span><span style="color: #000000; ">uchar</span><span style="color: #000000; ">></span><span style="color: #000000; ">(r[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">]</span><span style="color: #000000; ">/</span><span style="color: #000000; ">coef));<br /></span><span style="color: #008080; ">66</span> <span style="color: #000000; ">        }<br /></span><span style="color: #008080; ">67</span> <span style="color: #000000; ">}<br /></span><span style="color: #008080; ">68</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">69</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">70</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> main()<br /></span><span style="color: #008080; ">71</span> <span style="color: #000000; ">{<br /></span><span style="color: #008080; ">72</span> <span style="color: #000000; ">        namedWindow(title, WINDOW_AUTOSIZE);<br /></span><span style="color: #008080; ">73</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">74</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">const</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> r </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">10</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">75</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">76</span> <span style="color: #000000; ">        Mat img </span><span style="color: #000000; ">=</span><span style="color: #000000; "> imread(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">ai-sample.jpg</span><span style="color: #000000; ">"</span><span style="color: #000000; ">),<br /></span><span style="color: #008080; ">77</span> <span style="color: #000000; ">            kernel </span><span style="color: #000000; ">=</span><span style="color: #000000; "> kernelMatrix(r, (r </span><span style="color: #000000; ">-</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">) </span><span style="color: #000000; ">*</span><span style="color: #000000; "> </span><span style="color: #000000; ">0.3</span><span style="color: #000000; "> </span><span style="color: #000000; ">+</span><span style="color: #000000; "> </span><span style="color: #000000; ">0.8</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">78</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">79</span> <span style="color: #000000; ">        Mat product_v </span><span style="color: #000000; ">=</span><span style="color: #000000; "> Mat(img.cols, img.rows, img.type());<br /></span><span style="color: #008080; ">80</span> <span style="color: #000000; ">        Mat product_h </span><span style="color: #000000; ">=</span><span style="color: #000000; "> Mat(img.rows, img.cols, img.type());<br /></span><span style="color: #008080; ">81</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">82</span> <span style="color: #000000; ">        convolution(img, kernel, product_v);<br /></span><span style="color: #008080; ">83</span> <span style="color: #000000; ">        convolution(product_v, kernel, product_h);<br /></span><span style="color: #008080; ">84</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">85</span> <span style="color: #000000; ">        imshow(title, product_h);<br /></span><span style="color: #008080; ">86</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(; waitKey(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">) </span><span style="color: #000000; ">></span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">;);<br /></span><span style="color: #008080; ">87</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">88</span> <span style="color: #000000; ">        destroyWindow(title);<br /></span><span style="color: #008080; ">89</span> <span style="color: #000000; ">}</span></div><p><br /></p><img src="http://upload-images.jianshu.io/upload_images/610338-6d8a7ba9a3985876.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="渲染效果? data-original-src="http://upload-images.jianshu.io/upload_images/610338-6d8a7ba9a3985876.png" /><br /><div imagebubble"=""><div>渲染效果?/div> </div> </div></div><img src ="http://m.shnenglu.com/Shihira/aggbug/211542.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/Shihira/" target="_blank">Shihira</a> 2015-08-12 00:35 <a href="http://m.shnenglu.com/Shihira/archive/2015/08/12/211542.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AGG入门Q八Q?- 渲染http://m.shnenglu.com/Shihira/archive/2012/08/01/185867.htmlShihiraShihiraWed, 01 Aug 2012 12:01:00 GMThttp://m.shnenglu.com/Shihira/archive/2012/08/01/185867.htmlhttp://m.shnenglu.com/Shihira/comments/185867.htmlhttp://m.shnenglu.com/Shihira/archive/2012/08/01/185867.html#Feedback0http://m.shnenglu.com/Shihira/comments/commentRss/185867.htmlhttp://m.shnenglu.com/Shihira/services/trackbacks/185867.html一、引a
让我们来看一看渲染具体的程囑֐Q?/div>

上面提到了几个概念,再解释一下:
  • 点源(Vertex SourceQ:用顶点的方式描述矢量囑ŞQ?/li>
  • 光栅化(ResterizerQ:它的作用是把点源所描绘的图形与像素对应hQ可以说cM于Photoshop上的矢量蒙版Q?/li>
  • 扫描U(ScanlineQ:扫描U的作用是为扫描线渲染器提供一个扫描的方式和区域,使渲染器有序地填充;
  • 扫描U渲染器QScanline RendererQ:分实色和自定义渲染器两类Q实色只允许你用单一的颜色去q行渲染Q而自定则可做得多姿多彩,比如渐变、位图;它相当于GDI里的d?/li>

二、工?/h3>
q次我们以一个自制的点源与椭圆l合作ؓ渲染对象Q用宝蓝色的实色渲染器进行渲染;

#include <agg_ellipse.h>

//................

class triangle_path {
public:
    triangle_path()
    {
        unsigned tmp_array[4][3]={
            {0  , 250, agg::path_cmd_move_to},
            {500, 250, agg::path_cmd_line_to},
            {250, 500, agg::path_cmd_line_to},
            {0  ,   0, agg::path_cmd_stop}
        };
        memcpy(m_points[0], tmp_array[0], sizeof(m_points));
    }
    unsigned vertex(double *x, double* y)
    {
        *x = m_points[m_step][0];
        *y = m_points[m_step][1];
        unsigned r = m_points[m_step][2];
        m_step++;
        return r;
    }
    void rewind(int)
    {
        m_step = 0;
    }
private:
    int m_step;
    unsigned m_points[4][3];
};

//...... in class the_application

    void on_draw()
   {
        ren_bas.reset_clipping(true);
        ren_bas.clear(agg::rgba8(255, 255, 255));
 
        agg::ellipse ellipse(250, 125, 125, 125);
        triangle_path triangle;
        rasterizer.reset();
        rasterizer.add_path(triangle);
        rasterizer.add_path(ellipse);
        agg::render_scanlines_aa_solid(rasterizer, scanline, ren_bas,
            agg::rgba8(45, 108, 155));  //注意Q函数名中的scanline是复敎ͼQ?/span>
    }

三、解?/h3>
先看on_draw函数Q我们先定义了两个顶ҎQ一个是椭圆Q另一个是自制的三角ŞQ先把rasterizer重置Q清除上ơ重l留下的光栅信息Q我们再在光栅中dq两个顶ҎQ用渲染器渲染,是了;
你可能感到奇怪:Z么没有扫描线渲染器的定义呢?其实?span style="color: #ff0000; ">render_scanlines_aa_solid里,已l帮你定义好了实色渲染器。把render_scanlines_aa_solid展开成:

agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_rgb24>> renderer_scanline(ren_bas);
renderer_scanline.color(agg::rgba8(45, 108, 155, cover));
agg::render_scanlines(rasterizer, scanlines, renderer_scanline);
效率是一LQ只不过函数版本更加z?/div>
点源的定义Q结合上一节的知识和agg_basics.h中关于path_commands_e和path_flags_e的定义,应该是可以理解的Q?/div>


Shihira 2012-08-01 20:01 发表评论
]]>AGG入门Q七Q?- 点?/title><link>http://m.shnenglu.com/Shihira/archive/2012/07/24/183919.html</link><dc:creator>Shihira</dc:creator><author>Shihira</author><pubDate>Tue, 24 Jul 2012 08:30:00 GMT</pubDate><guid>http://m.shnenglu.com/Shihira/archive/2012/07/24/183919.html</guid><wfw:comment>http://m.shnenglu.com/Shihira/comments/183919.html</wfw:comment><comments>http://m.shnenglu.com/Shihira/archive/2012/07/24/183919.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://m.shnenglu.com/Shihira/comments/commentRss/183919.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/Shihira/services/trackbacks/183919.html</trackback:ping><description><![CDATA[<h3>一、修Ҏ?/h3> <div>现在l于q入了真正的矢量l图阶段Q我们的模版也需要有所改变Q至于ؓ什么,有什么作用,以后会说刎ͼ<br />包含下面的头文gQƈ且在the_applicationcMd两个成员?/div> <div> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #008000; ">//</span><span style="color: #008000; ">扫描U和扫描U光栅器</span><span style="color: #008000; "><br /> </span>#include <agg_scanline_u.h><br /> #include <agg_rasterizer_scanline_aa.h><br /> <br /> <span style="color: #0000FF; ">private</span>:<br />     <span style="color: #008000; ">//</span><span style="color: #008000; ">扫描U和扫描U光栅器</span><span style="color: #008000; "><br /> </span>    agg::scanline_u8 scanline;<br />     agg::rasterizer_scanline_aa<> rasterizer;</div> </div> <div> <p><br /> </p> <h3> 二、顶Ҏ</h3> <p> </p> <div>点源(Vertex SourceQ不是一个类Q而是一U类的模式。这U类里面有rewind()函数和vertex()函数lAGG内部调用Q没错,q就是它的定义)。类如其名,点源就是ؓl图pȝ提供点信息的,大家能想象得两个函数的作用了吗?</div> <div><strong>rewind()</strong>Q回到最开始个步骤Q?/div> <div><strong>vertex(double* x, double* y)</strong>Q每调用一ơ,跳一个步骤(点)Q每一个步骤都输出点的x,y坐标Q灰色字Q,以及q个坐标的绘囑֑令(紫色字)Q?br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/5.png" border="0" alt="" width="296" height="256" /></div> <div></div> <h3>三、内|顶Ҏ</h3> <div>AGG内置了大量的点源,我们可以直接调用Q他们包括:</div> <div><strong>agg::path_storage</strong></div> <div><strong>agg::arc</strong></div> <div><strong>agg::rounded_rect</strong></div> <div><strong>agg::ellipse</strong></div> <div><strong>agg::curve3</strong></div> <div><strong>agg::curve4 ......</strong></div> <div>{等Qؓ什么没有线、点点源?其实Qpath_storage已经内置了画U函数、画弧函数、画贝塞曲U函敎ͼ你可以用path_storage创造几乎Q何的囑Ş。至于画点,copy_pixel()或者用椭圆?#8230;…</div> <div></div> <h3>四、\径储存器</h3> <div>Path storage 是用来管理\径、画复杂囑Ş的。在上面可以Ld直线、曲Uѝ其他\径?/div> <h4>头文?/h4> <div><span style="color: #0000ff; ">#include</span> <agg_path_storage.h></div> <h4>cd定义</h4> <div><span style="color: #0000ff; ">typedef</span> path_base<vertex_block_storage<<span style="color: #0000ff; ">double</span>> > path_storage;</div> <h4>基本成员函数</h4> <div> <ul> <li><strong>move_to()</strong><br />     d命o?path_cmd_move_to 的顶点,意ؓ下一条线从这个点开始画Q?/li> <li><strong>line_to()</strong><br />     d命o?path_cmd_line_to 的顶点,意ؓȝ到这个点Q?/li> <li><strong>arc_to(double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x, double y)</strong><br />     d一条弧路径Q画轴长为rx, ryQ角度ؓangleQ优/劣弧Q顺逆时针,l点?x,y)?/li> <li><strong>curve3_to()</strong><br />     d贝塞曲U,参数Z个控制点和终点的坐标</li> <li><strong>curve4_to()</strong><br />     d贝塞曲U,参数Z个控制点和终点的坐标</li> <li><strong>join_path()</strong><br />     d一个顶ҎQ即l合</li> <li><strong>vertex(unsigned idx, double* x, double* y)<br /> last_vertex(double* x, double* y)<br /> vertex(double* x, double* y)</strong><br />     取顶点位|,前者ؓ已知步骤Q后两者ؓ序或倒序获取</li> <li><strong>modify_vertex()<br /> modify_command()</strong><br />     修改步骤为idx的顶点坐标和命o</li> </ul> </div> <div></div> <h3>五、其他顶Ҏ</h3> <div>其他点源就不一一介绍了,只列出其头文件和构造函敎ͼ</div> <div> <ul> <li><span style="color: #0000ff; ">#include <agg_ellipse.h></span><br /> <strong>ellipse(double x, double y, double rx, double ry, unsigned num_steps=0, bool cw=false)</strong><br />     圆心(x, y)和长短半轴分别ؓrx, ryQ步骤数位num_stepsQ无用)Qcw军_怺地方是否I出</li> <li><span style="color: #0000ff; ">#include <agg_arc.h></span><br /> <strong>arc(double x,  double y, double rx, double ry, double a1, double a2, bool ccw=true)</strong><br />     圆心?x, y)和长短半轴分别ؓrx, ryQ初始角度和l结角度为a1, a2</li> <li><span style="color: #0000ff; ">#include <agg_curves.h></span><br /> <strong>curve3(double x1, double y1, double x2, double y2, double x3, double y3)</strong><br />     三个点,分别为:初始点,控制点一Q终l点</li> <li><span style="color: #0000ff; ">#include <agg_curves.h></span><br /> <strong>curve4(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)</strong><br />     四个点,分别为:初始点,控制点一Q控制点二,l结?/li> <li><span style="color: #0000ff; ">#include <agg_rounded_rect.h></span><br /> <strong>rounded_rect(double x1, double y1, double x2, double r)</strong><br />     对角点的坐标和圆角半?/li> </ul> </div> <div></div> <p><strong style="color: #993300; ">至于怎样把他们画在渲染内存上呢,我们下一会讲到?/strong><strong style="color: red; "><br />头文件也渐渐地多了v来,包含头文件时的工作量有点大;我特地列了一个头文gQ里面已l包含了所有的AGG头文Ӟ以后大家只需要包含它好了?br />下蝲处:</strong><a href="http://m.shnenglu.com/Files/Shihira/agg.h.zip">http://m.shnenglu.com/Files/Shihira/agg.h.zip</a><a href="http://m.shnenglu.com/Files/Shihira/AGG.zip"></a></p> </div><img src ="http://m.shnenglu.com/Shihira/aggbug/183919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/Shihira/" target="_blank">Shihira</a> 2012-07-24 16:30 <a href="http://m.shnenglu.com/Shihira/archive/2012/07/24/183919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AGG入门Q六Q?- l习和细?/title><link>http://m.shnenglu.com/Shihira/archive/2012/07/24/183618.html</link><dc:creator>Shihira</dc:creator><author>Shihira</author><pubDate>Tue, 24 Jul 2012 08:30:00 GMT</pubDate><guid>http://m.shnenglu.com/Shihira/archive/2012/07/24/183618.html</guid><wfw:comment>http://m.shnenglu.com/Shihira/comments/183618.html</wfw:comment><comments>http://m.shnenglu.com/Shihira/archive/2012/07/24/183618.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.shnenglu.com/Shihira/comments/commentRss/183618.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/Shihira/services/trackbacks/183618.html</trackback:ping><description><![CDATA[<div>学到目前为止Q已l认识了六个cdQ?/div> <div> <ul> <li><strong>platform_support</strong></li> <li><strong>rendering_buffer</strong></li> <li><strong>rgba8</strong></li> <li><strong>pixfmt_rgb24</strong></li> <li><strong>rect_i</strong></li> <li><strong>renderer_base</strong></li> </ul> </div> <div>现在来做些练习,看看有没有掌握学q的东西Qƈ且灵z运用吧?/div> <div></div> <h3>一、基本框?/h3> <div>q一节的E序都以q个框架为基Q都是在on_draw中稍微改动的Q?/div> <div> <div style="background-color: #eeeeee; font-size: 13px; border:1px solid #CCCCCC; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->#include <agg_pixfmt_rgb.h><br /> #include <agg_renderer_base.h><br /> #include <platform/agg_platform_support.h><br /> <br /> <span style="color: #0000FF; ">class</span> the_application : <span style="color: #0000FF; ">public</span> agg::platform_support<br /> {<br /> <span style="color: #0000FF; ">public</span>:<br />     the_application(agg::pix_format_e format, <span style="color: #0000FF; ">bool</span> flip_y) : <br />         agg::platform_support(format, flip_y),<br />         pix_fmt(rbuf_window()),<br />         ren_bas(pix_fmt) <span style="color: #008000; ">//</span><span style="color: #008000; ">初始化渲染器</span><span style="color: #008000; "><br /> </span>    { }<br />     <br />     <span style="color: #0000FF; ">virtual</span> <span style="color: #0000FF; ">void</span> on_draw()<br />     {<br />          ren_bas.reset_clipping(true); <div>         ren_bas.clear(agg::rgba8(255, 255, 255));</div>     }<br /> <span style="color: #0000FF; ">private</span>:<br />     agg::pixfmt_rgb24 pix_fmt;<br />     agg::renderer_base<agg::pixfmt_rgb24> ren_bas;<br /> <br /> };<br /> <br /> <span style="color: #0000FF; ">int</span> agg_main(<span style="color: #0000FF; ">int</span> argc, <span style="color: #0000FF; ">char</span>* argv[])<br /> {<br />     the_application app(agg::pix_format_bgr24, <span style="color: #0000FF; ">true</span>);<br />     app.caption("AGG Test");<br />     <br />     <span style="color: #0000FF; ">if</span>(app.init(500, 500, agg::window_resize)) {<br />         <span style="color: #0000FF; ">return</span> app.run();<br />     }<br />     <span style="color: #0000FF; ">return</span> -1;<br /> }</div> </div> <h3>二、画U函?/h3> <p>~写如下函数Q实现在渲染~存中画U的功能Q无需反锯齿)Q?br />     <span style="color: #0000ff; ">inline void</span> stroke_line(<span style="color: #0000ff; ">int</span> x1, <span style="color: #0000ff; ">int</span> y1, <span style="color: #0000ff; ">int</span> x2, <span style="color: #0000ff; ">int</span> y2, agg::rgba8& color);<br /> 参数Q?br /> </p> <ul> <li>x1, y1, x2, y2分别是两个端点的坐标Q?/li> <li>color是颜Ԍ</li> </ul> <p> </p> <h3>三、画圆函?/h3> <p>~写如下函数Q实现在渲染~存中画圆的功能Q无需反锯齿)Q?br />     <span style="color: #0000ff; ">void</span> stroke_round(<span style="color: #0000ff; ">int</span> r, <span style="color: #0000ff; ">int</span> C_x, <span style="color: #0000ff; ">int</span> C_y, agg::rgba8& color, <span style="color: #0000ff; ">float </span>step = 0.01) <br /> 参数Q?br /> </p> <ul> <li>C_x, C_y 是圆心的坐标Q?/li> <li>color是颜Ԍ</li> <li>step是步长,也就是吧圆细分成1/step边ŞQ? </li> </ul> <p> </p> <h3>四、答?/h3> <div> <p> </p> <ul> <li>ȝ函数<br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->inline <span style="color: #0000FF; ">void</span> stroke_line(<span style="color: #0000FF; ">int</span> x1, <span style="color: #0000FF; ">int</span> y1, <span style="color: #0000FF; ">int</span> x2, <span style="color: #0000FF; ">int</span> y2, agg::rgba8& color)<br /> {<br />     <span style="color: #0000FF; ">double</span> precision = max(abs(x1 - x2), abs(y1 - y2));<br />     <span style="color: #008000; ">//</span><span style="color: #008000; ">_ֺQ也是d个?/span><span style="color: #008000; "><br /> </span><br />     <span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span> i=0; i <= precision; i++)<br />         ren_bas.copy_pixel( x1 + ( x2 - x1 ) / precision * i, <span style="color: #008000; ">//</span><span style="color: #008000; ">x</span><span style="color: #008000; "><br /> </span>            y1 + ( y2 - y1 ) / precision * i, <span style="color: #008000; ">//</span><span style="color: #008000; ">y</span><span style="color: #008000; "><br /> </span>            color);<br /> }</div> </li> <li>d函数<br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">void</span> stroke_round(<span style="color: #0000FF; ">int</span> r, <span style="color: #0000FF; ">int</span> C_x, <span style="color: #0000FF; ">int</span> C_y, agg::rgba8& color, <span style="color: #0000FF; ">float</span> step = 0.01)<br /> {<br />     <span style="color: #0000FF; ">int</span> prev_x = <span style="color: #0000FF; ">int</span>(r * cos(-0.01)) + C_x,<br />         prev_y = <span style="color: #0000FF; ">int</span>(r * sin(-0.01)) + C_y; <span style="color: #008000; ">//</span><span style="color: #008000; ">保存上一个点</span><span style="color: #008000; "><br /> </span><br />     <span style="color: #0000FF; ">int</span> x, y; <span style="color: #008000; ">//</span><span style="color: #008000; ">保存当前的点</span><span style="color: #008000; "><br /> </span>    <span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">double</span> rad = 0; rad < 2 * PI + step; rad+= step) {<br />         x = <span style="color: #0000FF; ">int</span>(r * cos(rad)) + C_x;<br />         y = <span style="color: #0000FF; ">int</span>(r * sin(rad)) + C_y; <span style="color: #008000; ">//</span><span style="color: #008000; ">计算弧度为rad时的坐标</span><span style="color: #008000; "><br /> </span>        stroke_line(x, y, prev_x, prev_y, color);<br />         prev_x = x; prev_y = y;<br />     }<br /> }</div> </li> </ul> <p>可能有的Z觉得奇怪的是,Z么在ȝ函数中,不用pix_fmt.copy_pixel()而用ren_bas.copy_pixel()呢?因ؓQ在pix_fmt中,混合器不q行查,像素拯的时候会拯到剪裁区域以外,q样会造成很奇怪的情况Q以至于如果写到了缓存以外,q会出现异常。注意,剪裁盒功能是基础渲染器别才提供的,更加底层的操作,比如像素格式混合和直接操作缓存,高层ơ的渲染器是无从理的。ؓ了安全v见,碰基础渲染器以下的工具……</p> </div> <div> </div><img src ="http://m.shnenglu.com/Shihira/aggbug/183618.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/Shihira/" target="_blank">Shihira</a> 2012-07-24 16:30 <a href="http://m.shnenglu.com/Shihira/archive/2012/07/24/183618.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AGG入门Q五Q?- 基础渲染?/title><link>http://m.shnenglu.com/Shihira/archive/2012/07/24/183556.html</link><dc:creator>Shihira</dc:creator><author>Shihira</author><pubDate>Tue, 24 Jul 2012 08:29:00 GMT</pubDate><guid>http://m.shnenglu.com/Shihira/archive/2012/07/24/183556.html</guid><wfw:comment>http://m.shnenglu.com/Shihira/comments/183556.html</wfw:comment><comments>http://m.shnenglu.com/Shihira/archive/2012/07/24/183556.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/Shihira/comments/commentRss/183556.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/Shihira/services/trackbacks/183556.html</trackback:ping><description><![CDATA[<div>基础渲染器(Base RendererQ是扫描U渲染器的基Q可以说Q正常情况下Q你l画M囑Ş、做M事,都需要通过它。而基渲染器需要你以模版的形式提供像素格式的信息,他将会通过像素格式混合器来实现渲染。其实,基础渲染器比像素格式混合器多了剪裁盒的功能,其他混合、拷贝什么的和像素格式؜合器是相似的Q这里就不列出来了?/div><div></div><h3>矩Şc?/h3><div>AGG装了一个专门表C矩形的模板crect_baseQ方便矩形的操作。下面用rect_i说明一下?       </div><h4>头文?/h4><div><span style="color: #0000ff; ">#include</span> "agg_basics.h"</div><h4>cd定义</h4><div><span style="color: #0000ff; ">typedef</span> rect_base<int> rect_i;</div><h4>基本成员函数</h4><div><ul><li><span style="color: #000080; "><strong>rect_i(x1, y1, x2, y2)<br /></strong></span>        构造函敎ͼl出最和最大坐标;</li><li><strong><font color="#000080">normalize()<br /></font></strong>        修正x1>x2或y1>y2的不合法矩ŞQ?/li><li><span style="color: #000080; "><strong>clip(rect_i& r)</strong></span><br />        取当前矩形与r怺的区域矩形作为当前矩形;</li><li><span style="color: #000080; "><strong>is_valid()</strong></span><br />        查矩形是否合法;</li><li><span style="color: #000080; "><strong>hit_test(int x, int y)<br /></strong></span>        ?x, y)是否在矩形内Q?/li></ul></div><div></div><h3>基础渲染?/h3><h4>头文?/h4><div><span style="color: #0000ff; ">#include</span> "agg_renderer_base"</div><h4>cd定义</h4><div><span style="color: #0000ff; ">template</span><class PixelFormat> class renderer_base</div><h4>基本成员函数</h4><div><ul><li><span style="color: #000080; "><strong>renderer_base(PixelFormat)<br /></strong></span>        构造函敎ͼ提供像素格式Q?/li><li><strong style="color: #000080; ">ren()<br /></strong>        q回像素格式对象Q?/li><li><span style="color: #000080; "><strong>clip_box(x1,y1,x2,y2)<br />clip_box_naked(x1,y1,x2,y2)<br /></strong></span>        讄当前剪裁盒ؓx1,y1,x2,y2围成的剪裁盒Q前者检查剪裁盒是否合法Q后者不查?/li><li><span style="color: #000080; "><strong>reset_clipping(bool visibility)<br /></strong></span>        重置剪裁盒,visibility军_剪裁盒是铺满H口Q可视)q是0Q不可视Q;</li><li><span style="color: #000080; "><strong>clip_box()<br />xmin()<br />ymin()<br />xmax()<br />ymax()<br /></strong></span>        q回当前剪裁盒矩形、以及纵横坐标;</li><li><span style="color: #000080; "><strong>copy_from()<br />blend_from()<br /></strong></span>        可以比较方便地、以矩Ş方式拯和؜合缓存里的图像了Q?/li></ul></div><img src ="http://m.shnenglu.com/Shihira/aggbug/183556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/Shihira/" target="_blank">Shihira</a> 2012-07-24 16:29 <a href="http://m.shnenglu.com/Shihira/archive/2012/07/24/183556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AGG入门Q四Q?- 渲染~存和؜合器http://m.shnenglu.com/Shihira/archive/2012/07/24/183204.htmlShihiraShihiraTue, 24 Jul 2012 08:29:00 GMThttp://m.shnenglu.com/Shihira/archive/2012/07/24/183204.htmlhttp://m.shnenglu.com/Shihira/comments/183204.htmlhttp://m.shnenglu.com/Shihira/archive/2012/07/24/183204.html#Feedback0http://m.shnenglu.com/Shihira/comments/commentRss/183204.htmlhttp://m.shnenglu.com/Shihira/services/trackbacks/183204.html一、上一节的代码
        agg::rendering_buffer &rbuf = rbuf_window();
        agg::pixfmt_rgb24 pixf(rbuf);

        agg::renderer_base<agg::pixfmt_rgb24> renb(pixf);
        renb.clear(agg::rgba8(255, 255, 255));

        pixf.copy_pixel(20, 20, agg::rgba8(0, 0, 255));

二、渲染缓?/h3>
渲染~存保存着一个个像素Q作为AGG的画布。它仅仅是一个内存块Q用来储存像素信息,不提供Q何绘囑֊能,只允怽d和修攚w面的数据。它也不告诉你里面的像素是灰度的、RGB的还是RGBA的,不告诉你从哪里到哪里是一个像?#8212;—它只是用来管理内存数据的?/div>

头文?/h4>
#include "platform/agg_platform_support.h"

cd定义

typedef row_accessor<int8u> rendering_buffer //int8u? bit无符h?/div>

基本成员函数

  • rendering_buffer(int8u* buf, unsigned width, unsigned height, int stride) 
            构造函敎ͼ指定事先分配好的内存块(到时qC面)首地址、宽高、一行的字节敎ͼ默认全部都是0Q;
  • row_ptr(int y)
            q回Wy行的首地址Q?/li>
  • copy_from(void *buf)
            从buf中拷贝像素;
  • clear(int8u value)
            用value清空~存
  • buf(), height(), weight(), stride()
            q回~存首地址、宽高、一行的字节敎ͼ
注:代码中的rbuf_window()是platform_support的一个成员函敎ͼ用于q回platform_support一开始帮你申L~存引用?/span>

三、؜合器

混合器的存在是ؓ了适应不同q_、不同需求下的不同像素格式。؜合器有三U:agg::rgbaQ?strong>agg::rgba8?strong>agg::rgba16Q都是用来指定颜色的Qrgba每个通道储存为doubleQrgba8为unsigned charQrgba16为int或long intQ؜合器起到的作用就像Win32API里的RGB和COLORREF宏?/div>

头文?/h4>
#include "agg_pixfmt_rgba.h"

cd定义

struct rgba8; //对,你没有看错,是结构,不是c?#8230;…

基本成员函数

  • rgba8(unsigned r, unsigned g, unsigned b, unsigned a)
            无须解释了吧Q最?55Q?/li>
  • clear(), no_color()
            四个通道全部清零Q也是变没色咯Q?/li>
  • transparent()
            alpha清零Q变透明Q?/li>
  • opacity()
            q回透明度,用double表示Q?/li>
  • gradient(agg::rgba8 &c, double k)
            颜色梯度Q就是颜色变Z原先的颜色渐变ؓcQ变化率为kQ?/li>
  • add(agg::rgba8 &c, unsinged cover)
            颜色叠加Q叠加一个透明度ؓcover/255的颜色cQ?/li>

成员变量

  • r, g, b, a都是无符h型;

四、像素格式؜合器


像素格式混合器的作用是直接操作像素(也就是缓存里保存的数据,但v码有个像素的样子Q,起到Win32API里的SetPixel()和GetPixel()的作用。像素格式由两个属性决定:混合器类?strong>【agg::rgba8/agg::rgba16?/strong>、bgr/rgb/rgba/abgr序【agg::order_bgr/agg::order_rgb/agg::order_rgba/agg::order_abgr?/strong>——q样Q共8U像素格式,它们起名字的规则是Q?/div>
agg::pixfmt_[order][bits*3];
下面用最常用的agg::pixfmt_rgb24来解释:

头文?/h4>
#include "agg_pixfmt_rgb.h"

cd定义

typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8,  order_rgb>, rendering_buffer> pixfmt_rgb24;

基本成员函数

  • pixfmt_rgb24(agg::rendering_buffer &) 
            构造函敎ͼ指定~存好Q?/li>
  • blend_pixel(agg::rgba8& c, int x, int y, int8u cover)
            用颜色c以coverQ覆盖率=透明度)的透明度؜合像?x, y)Q?/li>
  • copy_pixel(agg::rgba8& c, int x, int y)Qpixel(int x, int y)
            q个是相当于SetPixel()和GetPixel()了;
  • copy_hline(int x, int y, unsigned len, agg::rgba8& c)
    copy_vline(int x, int y, unsigned len, agg::rgba8& c)  
            ?x, y)开始打横(竖)序讄len长度的像素;
  • blend_hline(int x, int yQ?unsigned len, agg::rgba8& c, int8u cover)
    blend_vline(int x, int yQ?unsigned len, agg::rgba8& c, int8u cover) 
            ?x, y)开始打横(竖)序混合len长度的像素;
  • copy_solid_hspan(int x, int yQ?unsigned len, agg::rgba8* colors)
    copy_solid_vspan(int x, int yQ?unsigned len, agg::rgba8* colors)
    blend_solid_hspan(int x, int yQ?unsigned len, agg::rgba8* colors, int8u* cover, int8u cover)
    blend_solid_vspan(int x, int yQ?unsigned len, agg::rgba8* colors, int8u* cover, int8u cover)
            同上两个Q不q不是一个颜Ԍ是一pd的颜Ԍ
  • for_each_pixel(void (*f)(agg::rgba8* color))
            每一像素执行一遍fQ?/li>
  • copy_from(agg::rendering_buffer & from, int xdst, int ydst, int xsrc, int ysrc, unsigned len)
    blend_from(agg::rendering_buffer & from, int xdst, int ydst, int xsrc, int ysrc, unsigned len[, unsigned cover])  
            从缓存form?xsrc, ysrc)序复制Q؜合)到当前缓存的(xdst, ydst)中;
【其他函数和像素格式p靠大家的举一反三Q触cL通了……?/div>

五、结?/h3>
上面说的三者关pLQ؜合器混合RGBA四个通道Q像素格式؜合器混合像素Q像素格式؜合器操作的结果是使渲染缓存里的数据发生变化,而؜合器则不会,因ؓ它的作用仅仅是表C颜艌Ӏ?/div>

Shihira 2012-07-24 16:29 发表评论
]]>AGG入门Q三Q?- 渲染器介l?/title><link>http://m.shnenglu.com/Shihira/archive/2012/07/24/183117.html</link><dc:creator>Shihira</dc:creator><author>Shihira</author><pubDate>Tue, 24 Jul 2012 08:28:00 GMT</pubDate><guid>http://m.shnenglu.com/Shihira/archive/2012/07/24/183117.html</guid><wfw:comment>http://m.shnenglu.com/Shihira/comments/183117.html</wfw:comment><comments>http://m.shnenglu.com/Shihira/archive/2012/07/24/183117.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/Shihira/comments/commentRss/183117.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/Shihira/services/trackbacks/183117.html</trackback:ping><description><![CDATA[<h3>一、看回AGG入门Q二Q时on_draw()虚函数里的代码:</h3> <div> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->        agg::rendering_buffer &rbuf = rbuf_window();<br />         agg::pixfmt_rgb24 pixf(rbuf);<br /> <br />         agg::renderer_base<agg::pixfmt_rgb24> renb(pixf);<br />         renb.clear(agg::rgba8(255, 255, 255));<br /> <br />         pixf.copy_pixel(20, 20, agg::rgba8(0, 0, 255));</div> </div> <div></div> <h3>二、渲染器</h3> <h4>什么是渲染Q?/h4> <div>渲染是把内存中的l图指o真正执行的过E。比如说Q绘制一条线D,在内存里只会保存着两个端点的坐标和U段的宽度,而渲染就把这两个端点转换Z图、缓存甚xC屏上的一个个像素的数据。又比如_URZ面肯定是要有投媄的了Q但q个投媄的质量,q渲染器决定;U段是走LQAQ,q是反走LQBQ,靠的是渲染器的指o了?br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120713-1.png" border="0" alt="" width="392" height="193" /><br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120713-2.png" border="0" alt="" width="460" height="193" /></div> <h4>AGG里的渲染?/h4> <div>AGG分有多种渲染器。在AGG中,渲染器负责表现扫描线中的每个U段。在渲染器之前,AGG囑Ş中的U段是没有颜色值的Q只是位|、长度和 覆盖率(透明度)。渲染器赋于U段色彩Q最l成Zq完整的囑փ。其中最常用的是Q?/div> <div> <ul> <li>像素格式渲染?/li> <li>基础渲染?/li> <li>扫描U(反锯齿)渲染?/li> </ul> </div> <div></div> <h3>三、三U渲染器间的关系</h3> <div> <ul> <li>像素格式渲染器(PixelFormat RendererQ是最基础的渲染器Q不需要Q何其他渲染器的支持,所以可以直接声明;</li> <li>基础渲染器(Base RendererQ是中渲染器,需要像素格式作为模版和像素格式渲染器的支持;</li> <li>扫描U渲染器QScanline RendererQ是高渲染器,需要基渲染器作为模版和支持;</li> </ul> </div> <div>Q注Q模版主要是Z获取像素格式的信息)</div> <div></div> <blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> <div>所以,除像素格式渲染器声明为:<br /> <span style="color: #008000; ">agg::class object(agg::rendering_buffer &);</span><br />之外其他的渲染器都声明ؓQ?/div><div> <span style="color: #008000; ">agg::class<template> object(template &);</span></div> </blockquote> <div></div><img src ="http://m.shnenglu.com/Shihira/aggbug/183117.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/Shihira/" target="_blank">Shihira</a> 2012-07-24 16:28 <a href="http://m.shnenglu.com/Shihira/archive/2012/07/24/183117.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AGG入门Q一Q?- 配置开发环?/title><link>http://m.shnenglu.com/Shihira/archive/2012/07/24/183033.html</link><dc:creator>Shihira</dc:creator><author>Shihira</author><pubDate>Tue, 24 Jul 2012 08:28:00 GMT</pubDate><guid>http://m.shnenglu.com/Shihira/archive/2012/07/24/183033.html</guid><wfw:comment>http://m.shnenglu.com/Shihira/comments/183033.html</wfw:comment><comments>http://m.shnenglu.com/Shihira/archive/2012/07/24/183033.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://m.shnenglu.com/Shihira/comments/commentRss/183033.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/Shihira/services/trackbacks/183033.html</trackback:ping><description><![CDATA[<div>AGG是一个高效的、高质量的、开源的矢量囑Ş库,cM的有QGTK+的CairoQMicrosoft的GDI+。在三者中QAGG的性能是最高的Q不讨论Skia和Direct2DQ他们有OGL和DX的硬件加速,l图速度Ҏ不是一个档ơ的Q。让我们l数一下他的优~点Q?/div> <div></div> <div> <ul> <li>优点Q效率高Q质量高Q有反锯齿)Q功能强大,跨^台和q_GUI支持Q?#8230;…</li> <li>~点Q没有硬件加速,文档,门槛有那么点高,……</li> </ul> </div> <div> </div> <div></div> <h3>一、准?/h3> <div></div> <div> <ul> <li>?<a >http://www.antigrain.com/download/index.html</a>下蝲源码包?/li> <li>今天用Visual C++ 6.0来做IDE和编译器啦!要多l典有多l典?/li> </ul> </div> <div> </div> <div></div> <h3>二、工?/h3> <div></div> <div> <ol> <li>在VC6里新Z个工E?#8220;AGG”Q类型ؓ静态库Win32 Static Library<br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120712-1.png" border="0" alt="" width="420" height="70" /><br /> </li> <li>下列源文g都加入工E:<br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120712-2.png" border="0" alt="" width="466" height="102" /><br /> </li> <ol> <li><span style="color: #008000; ">./src/ 目录下所有cpp文g【核心库?</span></li> <li><span style="color: #008000; ">./src/ctrl/ 目录下所有cpp文g【控件库?</span></li> <li><span style="color: #008000; ">./src/platform/ 下对应^台目录(win32Q下的所有cpp文g【^台支持库?</span></li> <li><span style="color: #008000; ">./font_freetype/ 下所有的cpp文g【Freetype字体支持库?/span></li> <li><span style="color: #008000; ">./font_win32_tt/ 下所有的cpp文g【Truetype字体支持库?</span></li> <li><span style="color: #008000; ">./gpc/ 下所有的cpp文g【Generic Polygon Clipper裁切库?br /> </span></li> </ol> <li>下列目录加入ToolsQ工P菜单– OptionsQ选项Q菜?– DirectoryQ目录)选项卡中的Include Files目录列表中:<br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120712-3.png" border="0" alt="" /><br /> </li> <ol> <li><span style="color: #008000; ">./include/ *</span></li> <li><span style="color: #008000; ">./font_freetype/</span></li> <li><span style="color: #008000; ">./font_win32_tt/ *</span></li> <li><span style="color: #008000; ">./gpc/</span></li> </ol> <li>选择配置为Win32 ReleaseQ编?br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120712-4.png" border="0" alt="" width="418" height="64" /><br /> </li> <li>~译成功后,ToolsQ工P菜单– OptionsQ选项Q菜?– DirectoryQ目录)选项卡中的Library Files目录列表中加?【工E所在目录】\Release\<br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120712-5.png" border="0" alt="" width="426" height="57" /><br /> </li> <li> 没有成功~译的童鞋,奖励已经~译好的AGG.lib一?#8230;… <a href="/Files/Shihira/AGG.zip">AGG.zip</a><a></a></li> </ol> </div> <div></div> <h3>三、测?/h3> <div></div> <div> <ol> <li>新徏一个Win32 Application I工E,新徏一源文Ӟ加入下面的代码:<br /> <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->#include <agg_pixfmt_rgb.h><br /> #include <agg_renderer_base.h><br /> #include <platform/agg_platform_support.h><br /> <br /> <span style="color: #0000FF; ">class</span> the_application : <span style="color: #0000FF; ">public</span> agg::platform_support<br /> {<br /> <span style="color: #0000FF; ">public</span>:<br />     the_application(agg::pix_format_e format, <span style="color: #0000FF; ">bool</span> flip_y) : <br />         agg::platform_support(format, flip_y),<br />         pix_fmt(rbuf_window()),<br />         ren_bas(pix_fmt) <span style="color: #008000; ">//</span><span style="color: #008000; ">初始化渲染器</span><br />     { }<br /> <br />     <span style="color: #0000FF; ">virtual</span> <span style="color: #0000FF; ">void</span> on_draw()<br />     {<br />         ren_bas.reset_clipping(<span style="color: #0000FF; ">true</span>);<br />         ren_bas.clear(agg::rgba8(204, 204, 204));<br />     }<br /> <br /> <span style="color: #0000FF; ">private</span>:<br />     agg::pixfmt_rgb24 pix_fmt;<br />     agg::renderer_base<agg::pixfmt_rgb24> ren_bas;<br /> <br /> };<br /> <br /> <span style="color: #0000FF; ">int</span> agg_main(<span style="color: #0000FF; ">int</span> argc, <span style="color: #0000FF; ">char</span>* argv[])<br /> {<br />     the_application app(agg::pix_format_rgb24, <span style="color: #0000FF; ">true</span>);<br />     app.caption("AGG Test");<br />     <br />     <span style="color: #0000FF; ">if</span>(app.init(500, 500, agg::window_resize)) {<br />         <span style="color: #0000FF; ">return</span> app.run();<br />     }<br />     <span style="color: #0000FF; ">return</span> -1;<br /> }</div> </li> <li>在【工E】菜?- 【设|】菜?- 【连接】选项?- 【对?库模块】文本框 中加入AGG.lib</li> <li>~译q行Q不出意外,可以得到下面的结果:<br /> <img src="http://m.shnenglu.com/images/cppblog_com/shihira/20120712-6.png" border="0" alt="" width="385" height="129" /><br /></li> </ol> </div><img src ="http://m.shnenglu.com/Shihira/aggbug/183033.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/Shihira/" target="_blank">Shihira</a> 2012-07-24 16:28 <a href="http://m.shnenglu.com/Shihira/archive/2012/07/24/183033.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AGG入门Q二Q?- q_支持http://m.shnenglu.com/Shihira/archive/2012/07/24/183046.htmlShihiraShihiraTue, 24 Jul 2012 08:28:00 GMThttp://m.shnenglu.com/Shihira/archive/2012/07/24/183046.htmlhttp://m.shnenglu.com/Shihira/comments/183046.htmlhttp://m.shnenglu.com/Shihira/archive/2012/07/24/183046.html#Feedback1http://m.shnenglu.com/Shihira/comments/commentRss/183046.htmlhttp://m.shnenglu.com/Shihira/services/trackbacks/183046.html一、先看看下面的代码,q试着~译下:

#include <platform/agg_platform_support.h>
#include <agg_pixfmt_rgb.h>
#include <agg_renderer_base.h>
#include <stdio.h>

#include <agg_path_storage.h>

class the_application : public agg::platform_support
{
public:
    the_application(agg::pix_format_e format, bool flip_y) : 
        agg::platform_support(format, flip_y),
        pix_fmt(rbuf_window()),
        ren_bas(pix_fmt) //初始化渲染器
    {
    }

    virtual void on_draw()
    {
        ren_bas.reset_clipping(true);
        ren_bas.clear(agg::rgba8(255, 255, 255));
    }

    virtual void on_mouse_button_down(int x, int y, unsigned flags)
    {
        if(flags == agg::mouse_left) {
            char str[50];
            sprintf(str, "Mouse location:(%d, %d)", x, y);
            message(str);
        }
    }

    virtual void on_key(int x, int y, unsigned key, unsigned flags)
    {
        if(key == agg::key_return && flags == agg::kbd_shift) {
            unsigned img = 0, states;
            states = create_img(0, 500, 500);
            states = load_img(img, "Steve-and-Bill.bmp");
            copy_img_to_window(img);
            update_window();
        }
    }

private:
    agg::pixfmt_rgb24 pix_fmt;
    agg::renderer_base<agg::pixfmt_rgb24> ren_bas;

};

int agg_main(int argc, char* argv[])
{
    the_application app(agg::pix_format_rgb24, true);
    app.caption("AGG Test");
    
    if(app.init(500, 500, agg::window_resize)) {
        return app.run();
    }
    return -1;
}
如果不出意外Q在H口中点击鼠标左键将会出现对话框提示当前鼠标的位|,而按下Shift+Enter会在窗口中昄在工作目录下的位?#8220;Steve-and-Bill.bmp”Q?

二、解?/h3>
先看看头文gQplatform/agg_platform_support.hQ它里边定义了一个platform_supportc?#8212;—它允怽建立一个窗口来试你的囑ŞQƈ用鼠标键盘去控制它?

cd

  • class platform_support 

主要成员函数

  • platform_support(pix_format_e, bool) : 构造函数。设|窗口风格和y轴是否上下翻转;
  • width() Q返回窗口的宽;
  • height() Q返回窗口的高;
  • caption([ const char* ]) Q设|标题或q回标题字符Ԍ
  • format() Q?q回H口风格Q?/li>
  • message(const char*) Q弹出对话框Q没有风格可选)Q?/li>
  • run() Q运行窗口;
  • force_redraw() Q重l窗口,调用on_draw()Q?/li>
  • update_window() Q更新窗口,既是把渲染缓存中已有的内容写入窗口,不调用on_draw()?/li>
  • platform_support为我们提供了一个很好地l图q_Q它有一pd的函数可用于操作位图QBMP或PPMQ:
    • create_img()Q创Z个编号ؓidx的位图;
    • save_img()Q将位图idx保存到文件中Q?/li>
    • load_img()Q从文g中加载位囑ֈidx中;
    • copy_img_to_window()Q把idx拯到渲染缓存里Q?/li>
    • copy_img_to_img()Q把idx拯到另一q位NQ?/li>
    • copy_window_to_img() Q将渲染~存里的内容拯C图?/li>

虚函敎ͼ一般都是些消息Q要覆盖它以让消息@环调用)

  • on_init() Q窗口初始化时调用;
  • on_resize(int, int) Q改变大时调用Q?/li>
  • on_idle()  Q空闲时调用Q?/li>
  • on_mouse_move(int, int, unsigned) Q鼠标移动时调用Q?/li>
  • on_mouse_button_down(int, int, unsigned) Q鼠标按下时调用Q?/li>
  • on_mouse_button_up(int, int, unsigned)  Q鼠标弹h调用Q?/li>
  • on_key(int, int, unsigned, unsigned)  Q键盘打字时调用Q?/li>
  • on_draw()  Q窗口重l时调用?/li>

三、结?/h3>
platform_support 的功能不仅仅是这么多Q除此之外,他还能用控Ӟ{等。但很多时候,成熟的应用是不会使用它的Q因为它装了太多,虽然保证了跨q_性,却缺乏了自由性。platform_support 的主要作用是试囑փ和修改图像,方便工作和移?#8230;…q有Q方便初学者入?#8230;…



Shihira 2012-07-24 16:28 发表评论
]]> ƷŮٸaѾþ| þþþ޾Ʒþþþþþ| ƷۺϾþ| ޾Ʒþ| þþƷһAV| þ߳ˮ| ɫۺϾþ| þɫۺһ| þֻƷ99re66| þþƷAVɫ| yy6080þ| þþƷþ˼˼| һþþƷ| 99þþƷѿ| ƷѾþþþùһ| ٸִִˬëƬþú | wwwԾþþcom| ŷ޹Ʒþѿ| һaƬþëƬ| þþƷ| ɫۺϾþþþۺһ| Ʒþþþþô| AAAþþþƷ| ƷþóӰԺ| ĻƷѾþ5151 | 66ƷۺϾþþþþþ| 91ƷùۺϾþ| ŷþþþþ| 99Ʒþ| þþþ| Ʒþþþaaaa| þþĻձ| Ʒ18þþ⺾| þþWWWѾƷ| ޾ƷþþþĻ69| Ʒպŷþۺ| þˬˬƬAV| ƷŮþþm| 99þѹƷػ| Ʒþ| avþþþþòվ|