最近在做一个这样一个需求,一个控件可以实时预览摄像头的内容,并且对此图像进行高斯模糊处理,现在来记录一下。

基本的实现思路

1,摄像头实时预览的数据会回调给onPreviewFrame(byte[] data, Camera camera) ,通过这个获取YUV格式的数据。 
2,将YUV转换成RGB数组。 
3,cpu计算rgb数组或者gpu来处理图像。(这里用的cpu计算) 
github上有一个GPU实现高斯滤镜的开源项目,但是我觉得它的高斯模糊实现的不够好。 
android-gpuimage

开始onPreviewFrame(data)YUV420SP转RGBdoBlur()CPU计算结束

一,YUV420SP

在onPreviewFrame文档中有这么一段话。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*** Callback interface used to deliver copies of preview frames as* they are displayed.**<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @see</span> #setPreviewCallback(Camera.PreviewCallback)*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @see</span> #setOneShotPreviewCallback(Camera.PreviewCallback)*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @see</span> #setPreviewCallbackWithBuffer(Camera.PreviewCallback)*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @see</span> #startPreview()*/</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">PreviewCallback</span>{</span><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*** Called as preview frames are displayed.  This callback is invoked* on the event thread {@link #open(int)} was called from.** <p>If using the {@link android.graphics.ImageFormat#YV12} format,* refer to the equations in {@link Camera.Parameters#setPreviewFormat}* for the arrangement of the pixel data in the preview callback* buffers.**<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> data the contents of the preview frame in the format defined*  by {@link android.graphics.ImageFormat}, which can be queried*  with {@link android.hardware.Camera.Parameters#getPreviewFormat()}.*  If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}*             is never called, the default will be the YCbCr_420_SP*             (NV21) format.*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> camera the Camera service object.*/</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onPreviewFrame(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] data, Camera camera);};</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li></ul>

默认输出的格式YUV420SP,注释中的YCbCr就是YUV。 
YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值; 
而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

下面是拥有8个像素的YUV数组[4*2],YUV420SP即4个Y对应一个UV,如图,Y1,Y2,Y9,Y10对应U1,V1。 

二,YUV420SP转RGB

最主要是下面的转换公式:

<code class="hljs markdown has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">//ITU-R BT.601 conversionR = 1.164<span class="hljs-emphasis" style="box-sizing: border-box;">*(Y-16)+1.596*</span>(Cr-128)
G = 1.164<span class="hljs-emphasis" style="box-sizing: border-box;">*(Y-16)-0.392*</span>(Cb-128)-0.813*(Cr-128)
B = 1.164<span class="hljs-emphasis" style="box-sizing: border-box;">*(Y-16)+2.017*</span>(Cb-128)
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

或者

<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">R<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">''</span> = Y + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.140</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*V</span>
G<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">''</span> = Y - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>.<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">394</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*U</span> - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>.<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">581</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*V</span>
B<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">''</span> = Y + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.032</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*U</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

只是工业标准不同而已。下面截取android-gpu-image上面的代码并添加一些注释,网上有很多转换的方法,但是这个方法性能非常ok,耗时在10-20ms。为了最大可能获取性能,代码中乘法等都变成了位操作和加法的方式。

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> YUVtoARBG(JNIEnv * env, jobject obj, jbyteArray yuv420sp, jint width, jint height, jintArray rgbOut)
{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             sz;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             i;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             j;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             Y;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             Cr = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             Cb = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             pixPtr = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Y所占的空间</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             jDiv2 = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//uv前面行所占的空间</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             R = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             G = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             B = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>             cOff;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> w = width;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> h = height;sz = w * h;jint *rgbData = (jint*) ((*env)->GetPrimitiveArrayCritical(env, rgbOut, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>));jbyte* yuv = (jbyte*) (*env)->GetPrimitiveArrayCritical(env, yuv420sp, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j < h; j++) {pixPtr = j * w;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Y所占的空间</span>jDiv2 = j >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//除以2向下取整</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < w; i++) {Y = yuv[pixPtr];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Y < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) Y += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用位运算判断是奇数还是偶数</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>((i & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x1</span>) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {cOff = sz + jDiv2 * w + (i >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//计算 UV的位置  (i>>1)*2就是为了变成偶数  向下取整  因为U的游标都是偶数位</span>Cb = yuv[cOff];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Cb < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) Cb += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">127</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> Cb -= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">128</span>;Cr = yuv[cOff + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Cr < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) Cr += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">127</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> Cr -= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">128</span>;}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//ITU-R BT.601 conversion</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//     R = 1.164*(Y-16)+1.596*(Cr-128)</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//     G = 1.164*(Y-16)-0.392*(Cb-128)-0.813*(Cr-128)</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//     B = 1.164*(Y-16)+2.017*(Cb-128)</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>Y = Y + (Y >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>) + (Y >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>) + (Y >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Y=Y+Y*0.125+0.03125+0.00078</span>R = Y + Cb + (Cb >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) + (Cb >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>) + (Cb >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(R < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) R = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(R > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>) R = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>;G = Y - Cb + (Cb >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>) + (Cb >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>) - (Cr >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) + (Cr >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(G < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) G = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(G > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>) G = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>;B = Y + (Cr << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) + (Cr >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(B < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) B = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(B > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>) B = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>;rgbData[pixPtr++] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff000000</span> + (R << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>) + (G << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>) + B;}}(*env)->ReleasePrimitiveArrayCritical(env, rgbOut, rgbData, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);(*env)->ReleasePrimitiveArrayCritical(env, yuv420sp, yuv, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul>

三,高斯模糊

至于原理请看:高斯模糊 
这里用的FastBlur,之前考虑了RenderScript ,后来发现在实际使用中,最下方会出现闪烁的现象,故放弃。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> Bitmap <span class="hljs-title" style="box-sizing: border-box;">doBlur</span>(Bitmap sentBitmap, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> radius, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> canReuseInBitmap) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Stack Blur v1.0 from</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Java Author: Mario Klingemann <mario at quasimondo.com></span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// http://incubator.quasimondo.com</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// created Feburary 29, 2004</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Android port : Yahel Bouaziz <yahel at kayenko.com></span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// http://www.kayenko.com</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ported april 5th, 2012</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// This is a compromise between Gaussian Blur and Box blur</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// It creates much better looking blurs than Box Blur, but is</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 7x faster than my Gaussian Blur implementation.</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// I called it Stack Blur because this describes best how this</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// filter works internally: it creates a kind of moving stack</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// of colors whilst scanning through the image. Thereby it</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// just has to add one new block of color to the right side</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// of the stack and remove the leftmost color. The remaining</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// colors on the topmost layer of the stack are either added on</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// or reduced by one, depending on if they are on the right or</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// on the left side of the stack.</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// If you are using this algorithm in your code please add</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// the following line:</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com></span>Bitmap bitmap;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (canReuseInBitmap) {bitmap = sentBitmap;} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {bitmap = sentBitmap.copy(sentBitmap.getConfig(), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (radius < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> w = bitmap.getWidth();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> h = bitmap.getHeight();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[] pix = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[w * h];bitmap.getPixels(pix, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, w, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, w, h);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> wm = w - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hm = h - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> wh = w * h;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> div = radius + radius + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> r[] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[wh];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> g[] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[wh];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b[] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[wh];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> rsum, gsum, bsum, x, y, i, p, yp, yi, yw;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> vmin[] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[Math.max(w, h)];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> divsum = (div + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;divsum *= divsum;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> dv[] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">256</span> * divsum];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">256</span> * divsum; i++) {dv[i] = (i / divsum);}yw = yi = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[][] stack = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[div][<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> stackpointer;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> stackstart;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[] sir;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> rbs;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> r1 = radius + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> routsum, goutsum, boutsum;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> rinsum, ginsum, binsum;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (y = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; y < h; y++) {rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (i = -radius; i <= radius; i++) {p = pix[yi + Math.min(wm, Math.max(i, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>))];sir = stack[i + radius];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] = (p & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff0000</span>) >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>;sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = (p & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x00ff00</span>) >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>;sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>] = (p & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x0000ff</span>);rbs = r1 - Math.abs(i);rsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] * rbs;gsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] * rbs;bsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>] * rbs;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {rinsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];ginsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];binsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {routsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];goutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];boutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];}}stackpointer = radius;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (x = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; x < w; x++) {r[yi] = dv[rsum];g[yi] = dv[gsum];b[yi] = dv[bsum];rsum -= routsum;gsum -= goutsum;bsum -= boutsum;stackstart = stackpointer - radius + div;sir = stack[stackstart % div];routsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];goutsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];boutsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (y == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {vmin[x] = Math.min(x + radius + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, wm);}p = pix[yw + vmin[x]];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] = (p & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff0000</span>) >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>;sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = (p & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x00ff00</span>) >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>;sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>] = (p & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x0000ff</span>);rinsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];ginsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];binsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];rsum += rinsum;gsum += ginsum;bsum += binsum;stackpointer = (stackpointer + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) % div;sir = stack[(stackpointer) % div];routsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];goutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];boutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];rinsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];ginsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];binsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];yi++;}yw += w;}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (x = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; x < w; x++) {rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;yp = -radius * w;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (i = -radius; i <= radius; i++) {yi = Math.max(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, yp) + x;sir = stack[i + radius];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] = r[yi];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = g[yi];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>] = b[yi];rbs = r1 - Math.abs(i);rsum += r[yi] * rbs;gsum += g[yi] * rbs;bsum += b[yi] * rbs;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {rinsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];ginsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];binsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {routsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];goutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];boutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i < hm) {yp += w;}}yi = x;stackpointer = radius;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (y = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; y < h; y++) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Preserve alpha channel: ( 0xff000000 & pix[yi] )</span>pix[yi] = (<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff000000</span> & pix[yi]) | (dv[rsum] << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>) | (dv[gsum] << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>) | dv[bsum];rsum -= routsum;gsum -= goutsum;bsum -= boutsum;stackstart = stackpointer - radius + div;sir = stack[stackstart % div];routsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];goutsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];boutsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (x == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {vmin[y] = Math.min(y + r1, hm) * w;}p = x + vmin[y];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] = r[p];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = g[p];sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>] = b[p];rinsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];ginsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];binsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];rsum += rinsum;gsum += ginsum;bsum += binsum;stackpointer = (stackpointer + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) % div;sir = stack[stackpointer];routsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];goutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];boutsum += sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];rinsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];ginsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];binsum -= sir[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];yi += w;}}bitmap.setPixels(pix, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, w, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, w, h);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (bitmap);}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li><li style="box-sizing: border-box; padding: 0px 5px;">139</li><li style="box-sizing: border-box; padding: 0px 5px;">140</li><li style="box-sizing: border-box; padding: 0px 5px;">141</li><li style="box-sizing: border-box; padding: 0px 5px;">142</li><li style="box-sizing: border-box; padding: 0px 5px;">143</li><li style="box-sizing: border-box; padding: 0px 5px;">144</li><li style="box-sizing: border-box; padding: 0px 5px;">145</li><li style="box-sizing: border-box; padding: 0px 5px;">146</li><li style="box-sizing: border-box; padding: 0px 5px;">147</li><li style="box-sizing: border-box; padding: 0px 5px;">148</li><li style="box-sizing: border-box; padding: 0px 5px;">149</li><li style="box-sizing: border-box; padding: 0px 5px;">150</li><li style="box-sizing: border-box; padding: 0px 5px;">151</li><li style="box-sizing: border-box; padding: 0px 5px;">152</li><li style="box-sizing: border-box; padding: 0px 5px;">153</li><li style="box-sizing: border-box; padding: 0px 5px;">154</li><li style="box-sizing: border-box; padding: 0px 5px;">155</li><li style="box-sizing: border-box; padding: 0px 5px;">156</li><li style="box-sizing: border-box; padding: 0px 5px;">157</li><li style="box-sizing: border-box; padding: 0px 5px;">158</li><li style="box-sizing: border-box; padding: 0px 5px;">159</li><li style="box-sizing: border-box; padding: 0px 5px;">160</li><li style="box-sizing: border-box; padding: 0px 5px;">161</li><li style="box-sizing: border-box; padding: 0px 5px;">162</li><li style="box-sizing: border-box; padding: 0px 5px;">163</li><li style="box-sizing: border-box; padding: 0px 5px;">164</li><li style="box-sizing: border-box; padding: 0px 5px;">165</li><li style="box-sizing: border-box; padding: 0px 5px;">166</li><li style="box-sizing: border-box; padding: 0px 5px;">167</li><li style="box-sizing: border-box; padding: 0px 5px;">168</li><li style="box-sizing: border-box; padding: 0px 5px;">169</li><li style="box-sizing: border-box; padding: 0px 5px;">170</li><li style="box-sizing: border-box; padding: 0px 5px;">171</li><li style="box-sizing: border-box; padding: 0px 5px;">172</li><li style="box-sizing: border-box; padding: 0px 5px;">173</li><li style="box-sizing: border-box; padding: 0px 5px;">174</li><li style="box-sizing: border-box; padding: 0px 5px;">175</li><li style="box-sizing: border-box; padding: 0px 5px;">176</li><li style="box-sizing: border-box; padding: 0px 5px;">177</li><li style="box-sizing: border-box; padding: 0px 5px;">178</li><li style="box-sizing: border-box; padding: 0px 5px;">179</li><li style="box-sizing: border-box; padding: 0px 5px;">180</li><li style="box-sizing: border-box; padding: 0px 5px;">181</li><li style="box-sizing: border-box; padding: 0px 5px;">182</li><li style="box-sizing: border-box; padding: 0px 5px;">183</li><li style="box-sizing: border-box; padding: 0px 5px;">184</li><li style="box-sizing: border-box; padding: 0px 5px;">185</li><li style="box-sizing: border-box; padding: 0px 5px;">186</li><li style="box-sizing: border-box; padding: 0px 5px;">187</li><li style="box-sizing: border-box; padding: 0px 5px;">188</li><li style="box-sizing: border-box; padding: 0px 5px;">189</li><li style="box-sizing: border-box; padding: 0px 5px;">190</li><li style="box-sizing: border-box; padding: 0px 5px;">191</li><li style="box-sizing: border-box; padding: 0px 5px;">192</li><li style="box-sizing: border-box; padding: 0px 5px;">193</li><li style="box-sizing: border-box; padding: 0px 5px;">194</li><li style="box-sizing: border-box; padding: 0px 5px;">195</li><li style="box-sizing: border-box; padding: 0px 5px;">196</li><li style="box-sizing: border-box; padding: 0px 5px;">197</li><li style="box-sizing: border-box; padding: 0px 5px;">198</li><li style="box-sizing: border-box; padding: 0px 5px;">199</li><li style="box-sizing: border-box; padding: 0px 5px;">200</li><li style="box-sizing: border-box; padding: 0px 5px;">201</li><li style="box-sizing: border-box; padding: 0px 5px;">202</li><li style="box-sizing: border-box; padding: 0px 5px;">203</li><li style="box-sizing: border-box; padding: 0px 5px;">204</li><li style="box-sizing: border-box; padding: 0px 5px;">205</li><li style="box-sizing: border-box; padding: 0px 5px;">206</li><li style="box-sizing: border-box; padding: 0px 5px;">207</li><li style="box-sizing: border-box; padding: 0px 5px;">208</li><li style="box-sizing: border-box; padding: 0px 5px;">209</li><li style="box-sizing: border-box; padding: 0px 5px;">210</li><li style="box-sizing: border-box; padding: 0px 5px;">211</li><li style="box-sizing: border-box; padding: 0px 5px;">212</li><li style="box-sizing: border-box; padding: 0px 5px;">213</li><li style="box-sizing: border-box; padding: 0px 5px;">214</li><li style="box-sizing: border-box; padding: 0px 5px;">215</li><li style="box-sizing: border-box; padding: 0px 5px;">216</li><li style="box-sizing: border-box; padding: 0px 5px;">217</li><li style="box-sizing: border-box; padding: 0px 5px;">218</li><li style="box-sizing: border-box; padding: 0px 5px;">219</li><li style="box-sizing: border-box; padding: 0px 5px;">220</li><li style="box-sizing: border-box; padding: 0px 5px;">221</li><li style="box-sizing: border-box; padding: 0px 5px;">222</li><li style="box-sizing: border-box; padding: 0px 5px;">223</li><li style="box-sizing: border-box; padding: 0px 5px;">224</li><li style="box-sizing: border-box; padding: 0px 5px;">225</li><li style="box-sizing: border-box; padding: 0px 5px;">226</li><li style="box-sizing: border-box; padding: 0px 5px;">227</li><li style="box-sizing: border-box; padding: 0px 5px;">228</li><li style="box-sizing: border-box; padding: 0px 5px;">229</li><li style="box-sizing: border-box; padding: 0px 5px;">230</li><li style="box-sizing: border-box; padding: 0px 5px;">231</li><li style="box-sizing: border-box; padding: 0px 5px;">232</li><li style="box-sizing: border-box; padding: 0px 5px;">233</li><li style="box-sizing: border-box; padding: 0px 5px;">234</li></ul>

为了获取进一步的性能,我们可以做以下操作: 
1,设置一个vector,当vector中存在对象时,丢弃当前帧,绘制完后,清空vector,保证vector最多只有一个对象。 
2,先对图片进行缩小处理,高斯模糊后再放大。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//每次只处理一个图像,若前面的图像未处理完成,舍弃当前图像,提升性能</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(mVector.isEmpty()){Log.i(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"byte data ADD"</span>);mVector.add(data);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DrawTask().execute();}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="box-sizing: border-box; position: absolute; height: 60px; right: 30px; top: 5px; color: rgb(255, 255, 255); cursor: pointer; z-index: 2;"><a target=_blank target="_blank" style="box-sizing: border-box; color: rgb(12, 137, 207);"><img src="http://static.blog.csdn.net/images/save_snippets.png" style="border: none; box-sizing: border-box;" alt="" /></a></div>

因为onPreviewFrame()在主线程中,所以绘图一定要异步进行。

这里一个例子,提供大家参考:下载地址

Android 实时滤镜 高斯模糊(带源码)相关推荐

  1. C++版Android实时投屏软件系统源码,安卓手机投屏软件源码,无需root权限

    QtScrcpy QtScrcpy 可以通过 USB / 网络连接Android设备,并进行显示和控制.无需root权限. 同时支持 GNU/Linux ,Windows 和 MacOS 三大主流桌面 ...

  2. 覆盖式理解Android 消息处理机制(带源码解析)

    转载自:https://www.jianshu.com/p/02962454adf7 Android 消息处理机制估计都被写烂了,但是依然还是要写一下,因为Android应用程序是通过消息来驱动的,A ...

  3. android音乐播放器、多种架构综合应用、滤镜处理等源码

    Android仿微信朋友圈查看图片下拽返回. Android图片滤镜处理,相机滤镜处理效果源码 Android自定义View源码:一个水平的进度条 基于MVP-Clean + Weex + RxJav ...

  4. 面部表情识别3:Android实现表情识别(含源码,可实时检测)

    面部表情识别3:Android实现表情识别(含源码,可实时检测) 目录 面部表情识别3:Android实现表情识别(含源码,可实时检测) 1.面部表情识别方法 2.人脸检测方法 3.面部表情识别模型训 ...

  5. 行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测)

    行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测) 目录 行人检测(人体检测)3:Android实现人体检测(含源码,可实时人体检测) 1. 前言 2. 人体检测数据集说明 ...

  6. 跌倒检测和识别3:Android实现跌倒检测(含源码,可实时跌倒检测)

    跌倒检测和识别3:Android实现跌倒检测(含源码,可实时跌倒检测) 目录 跌倒检测和识别3:Android实现跌倒检测(含源码,可实时跌倒检测) 1. 前言 2. 跌倒检测数据集说明 3. 基于Y ...

  7. Linux自带的五子棋游戏,Android 五子棋游戏示例图与源码下载

    Android 五子棋游戏源码很多,下面是一款不错的Android五子棋游戏示例图及源码,导入Eclipse工程就可以使用了. Android 五子棋游戏部分源码: package five.itca ...

  8. android+高仿+日历,项目源码--Android天气日历精致UI源码

    技术要点: 1. 天气日历精致UI 2. Android的Http通信技术 3. Android的天气信息解析 4. Android的日历信息的统计 5. Andorid的地理位置的管理 6.源码带有 ...

  9. 最全的Android开源音乐播放器源码汇总

    收集了很多音乐播放器类的Android项目源码,非常不错的开源项目,会让你事半功倍,希望大家补充...谢谢! Android基于经纬度切歌的冲绳音乐播放器源码 http://neast.cn/foru ...

最新文章

  1. Learn OpenGL (七):摄像机
  2. 开源工程师:Ubuntu 应该抛弃 32 位 ISO 镜像
  3. webpack Entrypoint undefined = index.html
  4. 云原生之容器安全实践
  5. sql获取受影响行数、插入标识值
  6. IT 架构之学习教材 -WSSRA
  7. 微电子计算机是信息技术的,信息技术说第三十五说,计算机微电子技术
  8. GUID(GPT)分区格式安装Win7系统激活工具
  9. python_lintcode_52翻转字符串_128哈希函数
  10. matlab标记最大的连通区域,Matlab得到二值图像中最大连通区域
  11. 抽象类+接口+内部类作业题及答案
  12. Kinect安装与使用(一)
  13. poj1125Stockbroker Grapevine(最短路floyd)
  14. 无线无法解释服务器域名,科学网—Ubuntu 17.10 WIFI无线网络无法解析DNS域名的解决方法 - 徐勇刚的博文...
  15. 孙陶然:有态度就是进取
  16. UIColor 常用方法
  17. [通达OA二次开发]FineReport 与通达OA集成 如何实现统一登录。
  18. ssh密钥的生成与使用
  19. SimSolid无网格建模工程快速仿真软件
  20. 不畏浮云遮望眼 自缘身在云栖会

热门文章

  1. GB2312 编码(转)
  2. docker进入容器时报错 Error response from daemon: Container xxx is restarting, wait until the container is
  3. 根据ip查服务器信息,根据IP查询云服务器
  4. Unity CardboardSDK解析
  5. android 删除wifi文件,删除无线网络连接信号(wifi)(图文教程)
  6. linux线程篇,linux线程篇 (二) 线程的基本操作
  7. 量子计算机怎么储存,什么是量子计算机_量子计算机原理_量子计算的两种有效方法...
  8. Struts 2 studing
  9. Scrapy抓取新浪微博
  10. 【搬运】黑苹果台式机机型选择指导 By 黑果小兵