Android 手把手带你玩转自定义相机

来源:互联网 发布:搜索方式的算法 编辑:程序博客网 时间:2024/04/30 03:45

http://blog.csdn.net/qq_17250009/article/details/52795530

目录(?)[+]

  1. 概述
  2. 自定义相机的一般步骤
  3. 一般步骤的代码演示
  4. 真正的开始
  5. 自定义边边框框
    1. RectOnCamera
    2. 动起来
  6. 结束语
  7. 源码下载

概述

相机几乎是每个APP都要用到的功能,万一老板让你定制相机方不方?反正我是有点方。关于相机的两天奋斗总结免费送给你。

<code class="hljs avrasm has-numbering">  Intent intent = new Intent()<span class="hljs-comment">;  </span>  intent<span class="hljs-preprocessor">.setAction</span>(MediaStore<span class="hljs-preprocessor">.ACTION</span>_IMAGE_CAPTURE)<span class="hljs-comment">;  </span>  startActivity(intent)<span class="hljs-comment">;</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>

或者指定返回图片的名称mCurrentPhotoFile

<code class="hljs avrasm has-numbering">  Intent intent = new Intent(MediaStore<span class="hljs-preprocessor">.ACTION</span>_IMAGE_CAPTURE)<span class="hljs-comment">;</span>  intent<span class="hljs-preprocessor">.putExtra</span>(MediaStore<span class="hljs-preprocessor">.EXTRA</span>_OUTPUT,Uri<span class="hljs-preprocessor">.fromFile</span>(mCurrentPhotoFile))<span class="hljs-comment">;</span>  startActivityForResult(intent, CAMERA_WITH_DATA)<span class="hljs-comment">;</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>

2.自定义启动相机。

今天以第二种为例。效果图如下
demo

自定义相机的一般步骤

  1. 创建显示相机画面的布局,Android已经为我们选定好SurfaceView
  2. 通过SurfaceView#getHolder()获得链接CameraSurfaceViewSurfaceHolder
  3. Camame.open()打开相机
  4. 通过SurfaceHolder链接CameraurfaceView

一般步骤的代码演示

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CameraSurfaceView</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SurfaceView</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">SurfaceHolder</span>.<span class="hljs-title">Callback</span>, <span class="hljs-title">Camera</span>.<span class="hljs-title">AutoFocusCallback</span> {</span>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String TAG = <span class="hljs-string">"CameraSurfaceView"</span>;    <span class="hljs-keyword">private</span> Context mContext;    <span class="hljs-keyword">private</span> SurfaceHolder holder;    <span class="hljs-keyword">private</span> Camera mCamera;    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> mScreenWidth;    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> mScreenHeight;    <span class="hljs-keyword">public</span> <span class="hljs-title">CameraSurfaceView</span>(Context context) {        <span class="hljs-keyword">this</span>(context, <span class="hljs-keyword">null</span>);    }    <span class="hljs-keyword">public</span> <span class="hljs-title">CameraSurfaceView</span>(Context context, AttributeSet attrs) {        <span class="hljs-keyword">this</span>(context, attrs, <span class="hljs-number">0</span>);    }    <span class="hljs-keyword">public</span> <span class="hljs-title">CameraSurfaceView</span>(Context context, AttributeSet attrs, <span class="hljs-keyword">int</span> defStyleAttr) {        <span class="hljs-keyword">super</span>(context, attrs, defStyleAttr);        mContext = context;        getScreenMetrix(context);        initView();    }    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getScreenMetrix</span>(Context context) {        WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = <span class="hljs-keyword">new</span> DisplayMetrics();        WM.getDefaultDisplay().getMetrics(outMetrics);        mScreenWidth = outMetrics.widthPixels;        mScreenHeight = outMetrics.heightPixels;    }    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">initView</span>() {        holder = getHolder();<span class="hljs-comment">//获得surfaceHolder引用</span>        holder.addCallback(<span class="hljs-keyword">this</span>);        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);<span class="hljs-comment">//设置类型</span>    }    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">surfaceCreated</span>(SurfaceHolder holder) {        Log.i(TAG, <span class="hljs-string">"surfaceCreated"</span>);        <span class="hljs-keyword">if</span> (mCamera == <span class="hljs-keyword">null</span>) {            mCamera = Camera.open();<span class="hljs-comment">//开启相机</span>            <span class="hljs-keyword">try</span> {                mCamera.setPreviewDisplay(holder);<span class="hljs-comment">//摄像头画面显示在Surface上</span>            } <span class="hljs-keyword">catch</span> (IOException e) {                e.printStackTrace();            }        }    }    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">surfaceChanged</span>(SurfaceHolder holder, <span class="hljs-keyword">int</span> format, <span class="hljs-keyword">int</span> width, <span class="hljs-keyword">int</span> height) {        Log.i(TAG, <span class="hljs-string">"surfaceChanged"</span>);        mCamera.startPreview();    }    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">surfaceDestroyed</span>(SurfaceHolder holder) {        Log.i(TAG, <span class="hljs-string">"surfaceDestroyed"</span>);        mCamera.stopPreview();<span class="hljs-comment">//停止预览</span>        mCamera.release();<span class="hljs-comment">//释放相机资源</span>        mCamera = <span class="hljs-keyword">null</span>;        holder = <span class="hljs-keyword">null</span>;    }    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onAutoFocus</span>(<span class="hljs-keyword">boolean</span> success, Camera Camera) {        <span class="hljs-keyword">if</span> (success) {            Log.i(TAG, <span class="hljs-string">"onAutoFocus success="</span>+success);        }    }}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li></ul>

添加相机和自动聚焦限权

<code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.CAMERA"</span> /></span><span class="hljs-tag"><<span class="hljs-title">uses-feature</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.hardware.camera.autofocus"</span> /></span></code><ul class="pre-numbering"><li>1</li><li>2</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li></ul>

CameraSurfaceView放在布局文件中,这里建议最外层为FrameLayout,后面会用到。如此,我们便有了一个没有照相功能的相机。初次之外,仔细观察相机显示画面,图片是不是变形严重?那是因为我们还没有为相机设置各种参数。在预览前要设置摄像头的分辨率、预览分辨率和图片分辨率的宽高比保持一致。这样图片才不会变形。这是个比较难以理解的部分,想深刻理解还需读者自己动手去实践。

<code class="hljs avrasm has-numbering">   private void setCameraParams(Camera camera, int width, int height) {        Log<span class="hljs-preprocessor">.i</span>(TAG,<span class="hljs-string">"setCameraParams  width="</span>+width+<span class="hljs-string">"  height="</span>+height)<span class="hljs-comment">;</span>        Camera<span class="hljs-preprocessor">.Parameters</span> parameters = mCamera<span class="hljs-preprocessor">.getParameters</span>()<span class="hljs-comment">;</span>        // 获取摄像头支持的PictureSize列表        List<Camera<span class="hljs-preprocessor">.Size</span>> pictureSizeList = parameters<span class="hljs-preprocessor">.getSupportedPictureSizes</span>()<span class="hljs-comment">;</span>        for (Camera<span class="hljs-preprocessor">.Size</span> size : pictureSizeList) {            Log<span class="hljs-preprocessor">.i</span>(TAG, <span class="hljs-string">"pictureSizeList size.width="</span> + size<span class="hljs-preprocessor">.width</span> + <span class="hljs-string">"  size.height="</span> + size<span class="hljs-preprocessor">.height</span>)<span class="hljs-comment">;</span>        }        <span class="hljs-comment">/**从列表中选取合适的分辨率*/</span>        Camera<span class="hljs-preprocessor">.Size</span> picSize = getProperSize(pictureSizeList, ((float) height / width))<span class="hljs-comment">;</span>        if (null == picSize) {            Log<span class="hljs-preprocessor">.i</span>(TAG, <span class="hljs-string">"null == picSize"</span>)<span class="hljs-comment">;</span>            picSize = parameters<span class="hljs-preprocessor">.getPictureSize</span>()<span class="hljs-comment">;</span>        }        Log<span class="hljs-preprocessor">.i</span>(TAG, <span class="hljs-string">"picSize.width="</span> + picSize<span class="hljs-preprocessor">.width</span> + <span class="hljs-string">"  picSize.height="</span> + picSize<span class="hljs-preprocessor">.height</span>)<span class="hljs-comment">;</span>         // 根据选出的PictureSize重新设置SurfaceView大小        float w = picSize<span class="hljs-preprocessor">.width</span><span class="hljs-comment">;</span>        float h = picSize<span class="hljs-preprocessor">.height</span><span class="hljs-comment">;</span>        parameters<span class="hljs-preprocessor">.setPictureSize</span>(picSize<span class="hljs-preprocessor">.width</span>,picSize<span class="hljs-preprocessor">.height</span>)<span class="hljs-comment">;</span>        this<span class="hljs-preprocessor">.setLayoutParams</span>(new FrameLayout<span class="hljs-preprocessor">.LayoutParams</span>((int) (height*(h/w)), height))<span class="hljs-comment">;</span>        // 获取摄像头支持的PreviewSize列表        List<Camera<span class="hljs-preprocessor">.Size</span>> previewSizeList = parameters<span class="hljs-preprocessor">.getSupportedPreviewSizes</span>()<span class="hljs-comment">;</span>        for (Camera<span class="hljs-preprocessor">.Size</span> size : previewSizeList) {            Log<span class="hljs-preprocessor">.i</span>(TAG, <span class="hljs-string">"previewSizeList size.width="</span> + size<span class="hljs-preprocessor">.width</span> + <span class="hljs-string">"  size.height="</span> + size<span class="hljs-preprocessor">.height</span>)<span class="hljs-comment">;</span>        }        Camera<span class="hljs-preprocessor">.Size</span> preSize = getProperSize(previewSizeList, ((float) height) / width)<span class="hljs-comment">;</span>        if (null != preSize) {            Log<span class="hljs-preprocessor">.i</span>(TAG, <span class="hljs-string">"preSize.width="</span> + preSize<span class="hljs-preprocessor">.width</span> + <span class="hljs-string">"  preSize.height="</span> + preSize<span class="hljs-preprocessor">.height</span>)<span class="hljs-comment">;</span>            parameters<span class="hljs-preprocessor">.setPreviewSize</span>(preSize<span class="hljs-preprocessor">.width</span>, preSize<span class="hljs-preprocessor">.height</span>)<span class="hljs-comment">;</span>        }        parameters<span class="hljs-preprocessor">.setJpegQuality</span>(<span class="hljs-number">100</span>)<span class="hljs-comment">; // 设置照片质量</span>        if (parameters<span class="hljs-preprocessor">.getSupportedFocusModes</span>()<span class="hljs-preprocessor">.contains</span>(android<span class="hljs-preprocessor">.hardware</span><span class="hljs-preprocessor">.Camera</span><span class="hljs-preprocessor">.Parameters</span><span class="hljs-preprocessor">.FOCUS</span>_MODE_CONTINUOUS_PICTURE)) {            parameters<span class="hljs-preprocessor">.setFocusMode</span>(android<span class="hljs-preprocessor">.hardware</span><span class="hljs-preprocessor">.Camera</span><span class="hljs-preprocessor">.Parameters</span><span class="hljs-preprocessor">.FOCUS</span>_MODE_CONTINUOUS_PICTURE)<span class="hljs-comment">;// 连续对焦模式</span>        }        mCamera<span class="hljs-preprocessor">.cancelAutoFocus</span>()<span class="hljs-comment">;//自动对焦。</span>        // 设置PreviewDisplay的方向,效果就是将捕获的画面旋转多少度显示        // TODO 这里直接设置<span class="hljs-number">90</span>°不严谨,具体见https://developer<span class="hljs-preprocessor">.android</span><span class="hljs-preprocessor">.com</span>/reference/android/hardware/Camera<span class="hljs-preprocessor">.html</span><span class="hljs-preprocessor">#setPreviewDisplay%28android.view.SurfaceHolder%29</span>        mCamera<span class="hljs-preprocessor">.setDisplayOrientation</span>(<span class="hljs-number">90</span>)<span class="hljs-comment">;</span>        mCamera<span class="hljs-preprocessor">.setParameters</span>(parameters)<span class="hljs-comment">;</span>    }    <span class="hljs-comment">/**     * 从列表中选取合适的分辨率     * 默认w:h = 4:3     * <p>tip:这里的w对应屏幕的height     *            h对应屏幕的width<p/>     */</span>    private Camera<span class="hljs-preprocessor">.Size</span> getProperSize(List<Camera<span class="hljs-preprocessor">.Size</span>> pictureSizeList, float screenRatio) {        Log<span class="hljs-preprocessor">.i</span>(TAG, <span class="hljs-string">"screenRatio="</span> + screenRatio)<span class="hljs-comment">;</span>        Camera<span class="hljs-preprocessor">.Size</span> result = null<span class="hljs-comment">;</span>        for (Camera<span class="hljs-preprocessor">.Size</span> size : pictureSizeList) {            float currentRatio = ((float) size<span class="hljs-preprocessor">.width</span>) / size<span class="hljs-preprocessor">.height</span><span class="hljs-comment">;</span>            if (currentRatio - screenRatio == <span class="hljs-number">0</span>) {                result = size<span class="hljs-comment">;</span>                <span class="hljs-keyword">break</span><span class="hljs-comment">;</span>            }        }        if (null == result) {            for (Camera<span class="hljs-preprocessor">.Size</span> size : pictureSizeList) {                float curRatio = ((float) size<span class="hljs-preprocessor">.width</span>) / size<span class="hljs-preprocessor">.height</span><span class="hljs-comment">;</span>                if (curRatio == <span class="hljs-number">4</span>f / <span class="hljs-number">3</span>) {// 默认w:h = <span class="hljs-number">4</span>:<span class="hljs-number">3</span>                    result = size<span class="hljs-comment">;</span>                    <span class="hljs-keyword">break</span><span class="hljs-comment">;</span>                }            }        }        return result<span class="hljs-comment">;</span>    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li></ul>

进去的是屏幕宽高,出来的是调整好了的参数。在surfaceChanged方法中执行mCamera.startPreview(); 前调用setCameraParams(mCamera, mScreenWidth, mScreenHeight); 就可以了。最后要在AndroidManifest.xml里设置activity的方向Android:screenOrientation="portrait"代码里有很多注释,其中也有我自己调试时候的Log,大家可以自己调试下,看看不同参数的效果。昨天调参数搞到一点多,都在折腾这个函数。唉,一把辛酸泪。
身为一个相机,居然不能照相?真是太丢脸了!下面给我们的相机添加上照相的功能。照相核心代码就一句:mCamera.takePicture(null, null, jpeg);
可以看到takePicture方法有三个参数,分别是ShutterCallbackPictureCallbackPictureCallback。这里我们只用了PictureCallback

<code class="hljs java has-numbering">    <span class="hljs-comment">// 拍照瞬间调用</span>    <span class="hljs-keyword">private</span> Camera.ShutterCallback shutter = <span class="hljs-keyword">new</span> Camera.ShutterCallback() {        <span class="hljs-annotation">@Override</span>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onShutter</span>() {            Log.i(TAG,<span class="hljs-string">"shutter"</span>);        }    };    <span class="hljs-comment">// 获得没有压缩过的图片数据</span>    <span class="hljs-keyword">private</span> Camera.PictureCallback raw = <span class="hljs-keyword">new</span> Camera.PictureCallback() {        <span class="hljs-annotation">@Override</span>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onPictureTaken</span>(<span class="hljs-keyword">byte</span>[] data, Camera Camera) {            Log.i(TAG, <span class="hljs-string">"raw"</span>);        }    };    <span class="hljs-comment">//创建jpeg图片回调数据对象</span>    <span class="hljs-keyword">private</span> Camera.PictureCallback jpeg = <span class="hljs-keyword">new</span> Camera.PictureCallback() {        <span class="hljs-annotation">@Override</span>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onPictureTaken</span>(<span class="hljs-keyword">byte</span>[] data, Camera Camera) {            BufferedOutputStream bos = <span class="hljs-keyword">null</span>;            Bitmap bm = <span class="hljs-keyword">null</span>;            <span class="hljs-keyword">try</span> {                <span class="hljs-comment">// 获得图片</span>                bm = BitmapFactory.decodeByteArray(data, <span class="hljs-number">0</span>, data.length);                <span class="hljs-keyword">if</span> (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {                    Log.i(TAG, <span class="hljs-string">"Environment.getExternalStorageDirectory()="</span>+Environment.getExternalStorageDirectory());                    String filePath = <span class="hljs-string">"/sdcard/dyk"</span>+System.currentTimeMillis()+<span class="hljs-string">".jpg"</span>;<span class="hljs-comment">//照片保存路径</span>                    File file = <span class="hljs-keyword">new</span> File(filePath);                    <span class="hljs-keyword">if</span> (!file.exists()){                        file.createNewFile();                    }                    bos = <span class="hljs-keyword">new</span> BufferedOutputStream(<span class="hljs-keyword">new</span> FileOutputStream(file));                    bm.compress(Bitmap.CompressFormat.JPEG, <span class="hljs-number">100</span>, bos);<span class="hljs-comment">//将图片压缩到流中</span>                }<span class="hljs-keyword">else</span>{                    Toast.makeText(mContext,<span class="hljs-string">"没有检测到内存卡"</span>, Toast.LENGTH_SHORT).show();                }            } <span class="hljs-keyword">catch</span> (Exception e) {                e.printStackTrace();            } <span class="hljs-keyword">finally</span> {                <span class="hljs-keyword">try</span> {                    bos.flush();<span class="hljs-comment">//输出</span>                    bos.close();<span class="hljs-comment">//关闭</span>                    bm.recycle();<span class="hljs-comment">// 回收bitmap空间</span>                    mCamera.stopPreview();<span class="hljs-comment">// 关闭预览</span>                    mCamera.startPreview();<span class="hljs-comment">// 开启预览</span>                } <span class="hljs-keyword">catch</span> (IOException e) {                    e.printStackTrace();                }            }        }    };</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li></ul>

jpeg#onPictureTaken()里。我们将存储照片信息的byte[] data解析成bitmap,然后转换成JPG格式的图片保存在SD卡中。注意finally中最后两句mCamera.stopPreview();// 关闭预览 mCamera.startPreview();// 开启预览 上文也提到:当调用camera.takePiture()方法后,camera关闭了预览,这时需要调用startPreview()来重新开启预览。如果不再次开启预览,则会一直停留在拍摄照片画面。为了方便外部调用拍照。这里我暴露了一个方法供外部拍照。

<code class="hljs cs has-numbering">    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">takePicture</span>(){        <span class="hljs-comment">//设置参数,并拍照</span>        setCameraParams(mCamera, mScreenWidth, mScreenHeight);        <span class="hljs-comment">// 当调用camera.takePiture方法后,camera关闭了预览,这时需要调用startPreview()来重新开启预览</span>        mCamera.takePicture(<span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, jpeg);    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>

在布局文件中添加一个Button,点击Button执行takePicture()方法。不要忘了添加写SD卡限权

<code class="hljs xml has-numbering"><span class="hljs-tag"><<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.WRITE_EXTERNAL_STORAGE"</span> /></span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li></ul>

至此,一个具有照相并保存拍摄图片功能的相机就做出来了。But,我们就此满足了吗?要是为了这些简单的功能我也不会写这篇博客。这只是个开始

真正的开始

别人APP在照相的时候,屏幕上居然可以显示像效果图那样的框框啦、辅助点啦、图片bulabulabula~。在网上搜索一番实现方式,再加上一些自己的理解,构成了这篇博客。
上文布局文件一直没有贴,现在贴出来大家先扫一眼,有些控件会在接下来展示

<code class="hljs xml has-numbering"><span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span><span class="hljs-tag"><<span class="hljs-title">FrameLayout</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>    <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>    <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span>    <span class="hljs-tag"><<span class="hljs-title">com.dyk.cameratest.view.CameraSurfaceView</span>        <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/cameraSurfaceView"</span>        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>        <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> /></span>    <span class="hljs-tag"><<span class="hljs-title">com.dyk.cameratest.view.RectOnCamera</span>        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>        <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> /></span>    <span class="hljs-tag"><<span class="hljs-title">RelativeLayout</span>        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>        <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span>        <span class="hljs-tag"><<span class="hljs-title">Button</span>            <span class="hljs-attribute">android:layout_alignParentBottom</span>=<span class="hljs-value">"true"</span>            <span class="hljs-attribute">android:layout_centerHorizontal</span>=<span class="hljs-value">"true"</span>            <span class="hljs-attribute">android:layout_marginBottom</span>=<span class="hljs-value">"20dp"</span>            <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/takePic"</span>            <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"80dp"</span>            <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"50dp"</span>            <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"#88427ac7"</span>            <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"拍照"</span>            <span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"#aaa"</span> /></span>    <span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span><span class="hljs-tag"></<span class="hljs-title">FrameLayout</span>></span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul>

布局文件的最外层是个FrameLayout,我们知道FrameLayout是自带覆盖效果的。由来这个思路接下来就很简单了。编程重要的是思想,思想有了,其余的就剩具体的实现细节。

自定义边边框框

为了和CameraSurfaceView区分开,再自定义一个RectOnCamera专门用来画边边框框这些东西。这样做还一个好处是方便维护,不至于将所有东西都放在一个View中。

RectOnCamera

<code class="hljs java has-numbering"><span class="hljs-keyword">package</span> com.dyk.cameratest.view;...<span class="hljs-javadoc">/** * Created by 一口仨馍 on 2016/4/7. */</span><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RectOnCamera</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">View</span> {</span>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String TAG = <span class="hljs-string">"CameraSurfaceView"</span>;    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> mScreenWidth;    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> mScreenHeight;    <span class="hljs-keyword">private</span> Paint mPaint;    <span class="hljs-keyword">private</span> RectF mRectF;    <span class="hljs-comment">// 圆</span>    <span class="hljs-keyword">private</span> Point centerPoint;    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> radio;    <span class="hljs-keyword">public</span> <span class="hljs-title">RectOnCamera</span>(Context context) {        <span class="hljs-keyword">this</span>(context, <span class="hljs-keyword">null</span>);    }    <span class="hljs-keyword">public</span> <span class="hljs-title">RectOnCamera</span>(Context context, AttributeSet attrs) {        <span class="hljs-keyword">this</span>(context, attrs, <span class="hljs-number">0</span>);    }    <span class="hljs-keyword">public</span> <span class="hljs-title">RectOnCamera</span>(Context context, AttributeSet attrs, <span class="hljs-keyword">int</span> defStyleAttr) {        <span class="hljs-keyword">super</span>(context, attrs, defStyleAttr);        getScreenMetrix(context);        initView(context);    }    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getScreenMetrix</span>(Context context) {        WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = <span class="hljs-keyword">new</span> DisplayMetrics();        WM.getDefaultDisplay().getMetrics(outMetrics);        mScreenWidth = outMetrics.widthPixels;        mScreenHeight = outMetrics.heightPixels;    }    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">initView</span>(Context context) {        mPaint = <span class="hljs-keyword">new</span> Paint();        mPaint.setAntiAlias(<span class="hljs-keyword">true</span>);<span class="hljs-comment">// 抗锯齿</span>        mPaint.setDither(<span class="hljs-keyword">true</span>);<span class="hljs-comment">// 防抖动</span>        mPaint.setColor(Color.RED);        mPaint.setStrokeWidth(<span class="hljs-number">5</span>);        mPaint.setStyle(Paint.Style.STROKE);<span class="hljs-comment">// 空心</span>        <span class="hljs-keyword">int</span> marginLeft = (<span class="hljs-keyword">int</span>) (mScreenWidth*<span class="hljs-number">0.15</span>);        <span class="hljs-keyword">int</span> marginTop = (<span class="hljs-keyword">int</span>) (mScreenHeight * <span class="hljs-number">0.25</span>);        mRectF = <span class="hljs-keyword">new</span> RectF(marginLeft, marginTop, mScreenWidth - marginLeft, mScreenHeight - marginTop);        centerPoint = <span class="hljs-keyword">new</span> Point(mScreenWidth/<span class="hljs-number">2</span>, mScreenHeight/<span class="hljs-number">2</span>);        radio = (<span class="hljs-keyword">int</span>) (mScreenWidth*<span class="hljs-number">0.1</span>);    }    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onDraw</span>(Canvas canvas) {        <span class="hljs-keyword">super</span>.onDraw(canvas);        mPaint.setColor(Color.RED);        canvas.drawRect(mRectF, mPaint);        mPaint.setColor(Color.WHITE);        Log.i(TAG, <span class="hljs-string">"onDraw"</span>);        canvas.drawCircle(centerPoint.x,centerPoint.y, radio,mPaint);<span class="hljs-comment">// 外圆</span>        canvas.drawCircle(centerPoint.x,centerPoint.y, radio - <span class="hljs-number">20</span>,mPaint); <span class="hljs-comment">// 内圆</span>    }}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li></ul>

这里简单的画了一个类似二维码扫描的框框,还有一个类似聚焦的内外圆。那么问题来了,聚焦的内外圆要随着手指滑而改变位置,而且要有聚焦的效果。可又和具有聚焦功能的CameraSurfaceView不是同一个类,不仅如此聚焦内外圆还完全覆盖了CameraSurfaceView。要处理这种问题,需要接口回调。这就是思想下面的细节。现在虽然确定接口回调,但还有一个问题,CameraSurfaceView类和RectOnCamera类中都没有对方的对象或者引用。没错,通过共同持有RectOnCameraCameraSurfaceViewActivity可以实现此功能。下面是具体的实现方法

动起来

首先,想要随着手指的滑动而改变RectOnCamera的位置肯定是要复写onTouchEvent()方法

<code class="hljs cs has-numbering">    @Override    <span class="hljs-keyword">public</span> boolean <span class="hljs-title">onTouchEvent</span>(MotionEvent <span class="hljs-keyword">event</span>) {        <span class="hljs-keyword">switch</span> (<span class="hljs-keyword">event</span>.getAction()){            <span class="hljs-keyword">case</span> MotionEvent.ACTION_DOWN:            <span class="hljs-keyword">case</span> MotionEvent.ACTION_MOVE:            <span class="hljs-keyword">case</span> MotionEvent.ACTION_UP:                <span class="hljs-keyword">int</span> x = (<span class="hljs-keyword">int</span>) <span class="hljs-keyword">event</span>.getX();                <span class="hljs-keyword">int</span> y = (<span class="hljs-keyword">int</span>) <span class="hljs-keyword">event</span>.getY();                centerPoint = <span class="hljs-keyword">new</span> Point(x, y);                invalidate();                <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;        }        <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul>

其次,定义回调接口

<code class="hljs java has-numbering"> <span class="hljs-keyword">private</span> IAutoFocus mIAutoFocus;    <span class="hljs-javadoc">/** 聚焦的回调接口 */</span>    <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span>  <span class="hljs-title">IAutoFocus</span>{</span>        <span class="hljs-keyword">void</span> autoFocus();    }    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setIAutoFocus</span>(IAutoFocus mIAutoFocus) {        <span class="hljs-keyword">this</span>.mIAutoFocus = mIAutoFocus;    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>

onTouchEvent()return前加入

<code class="hljs cs has-numbering">  <span class="hljs-keyword">if</span> (mIAutoFocus != <span class="hljs-keyword">null</span>){      mIAutoFocus.autoFocus();  }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>

至此我们的回调接口已经定义好了,此时还需要CameraSurfaceView暴露一个聚焦方法,以便Activity调用

<code class="hljs cs has-numbering">    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAutoFocus</span>(){        mCamera.autoFocus(<span class="hljs-keyword">this</span>);    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>

准备工作已经全部完成,下面请看Activity的具体实现:

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">View</span>.<span class="hljs-title">OnClickListener</span>,<span class="hljs-title">RectOnCamera</span>.<span class="hljs-title">IAutoFocus</span>{</span>    <span class="hljs-keyword">private</span> CameraSurfaceView mCameraSurfaceView;    <span class="hljs-keyword">private</span> RectOnCamera mRectOnCamera;    <span class="hljs-keyword">private</span> Button takePicBtn;    <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> isClicked;    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        <span class="hljs-comment">// 全屏显示     </span>        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                            WindowManager.LayoutParams.FLAG_FULLSCREEN);        setContentView(R.layout.activity_main);        mCameraSurfaceView = (CameraSurfaceView) findViewById(R.id.cameraSurfaceView);        mRectOnCamera = (RectOnCamera) findViewById(R.id.rectOnCamera);        takePicBtn= (Button) findViewById(R.id.takePic);        mRectOnCamera.setIAutoFocus(<span class="hljs-keyword">this</span>);        takePicBtn.setOnClickListener(<span class="hljs-keyword">this</span>);    }    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClick</span>(View v) {        <span class="hljs-keyword">switch</span> (v.getId()){            <span class="hljs-keyword">case</span> R.id.takePic:                mCameraSurfaceView.takePicture();                <span class="hljs-keyword">break</span>;            <span class="hljs-keyword">default</span>:                <span class="hljs-keyword">break</span>;        }    }    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">autoFocus</span>() {        mCameraSurfaceView.setAutoFocus();    }}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li></ul>

可以看到,MainActivity实现了IAutoFocus接口,并且在复写的IAutoFocus#autoFocus()方法中,调用了CameraSurfaceView暴露出来的方法setAutoFocus()。至此,在RectOnCamera每次的滑动过程中都会改变聚焦内外圆的位置,还会增加聚焦功能。一心二用甚至一心多用岂不是更好。

结束语

在经历两次断电没保存和一次CSDN服务器错误内容丢失之后终究还是完成了这篇博客,实属不易。十分感谢能听我啰嗦到结尾~

PS:Demo界面并没有做的很精致,只是提供了一种思路。按照此思路能做出比较华丽的效果,授人以鱼不如授人以渔。

2016.10.12 在经历了上述种种磨难之后,终于发表了这篇博文,然而发表没几天,被我自己覆盖了。这下博文是真的丢了。心塞ing。今天没事百度下自己CSDN昵称“一口仨馍”,发现其他网站爬过这篇博文,随后我复制了自己原创的博文,再次发表。感谢那些爬我博文还不署名的网站。谢谢你全家。

源码下载

http://download.csdn.net/detail/qq_17250009/9484160

0 0
原创粉丝点击