EasyCamera–更简单更灵活的相机应用编写

EasyCamera–更简单更灵活的相机应用编写最近开工做项目了,需要前期准备下技术,项目中需要用到Camera的相关技术,偶然在GitHub上发现了这个东西–EasyCamera,使得调用相机的相关操作变得更加简单了。这样我们先把Github上的文件先clone一下,将zip文件下载下来,然后解压,由于这个项目还是用的Eclipse构建,用Eclipse的用户就可以跳过这一段了。为了构建方便我们自己新建一个Library的Modul

最近开工做项目了,需要前期准备下技术,项目中需要用到Camera的相关技术,偶然在GitHub上发现了这个东西–EasyCamera,使得调用相机的相关操作变得更加简单了。

这样我们先把Github上的文件先clone一下,将zip文件下载下来,然后解压,由于这个项目还是用的Eclipse构建,用Eclipse的用户就可以跳过这一段了。

为了构建方便我们自己新建一个Library的Module,这样走File->New Module到达下面这个页面:

EasyCamera--更简单更灵活的相机应用编写

按照图片中选中的点击Next,然后需要给你的Library来一个名字,然后到达这个页面:

EasyCamera--更简单更灵活的相机应用编写

选择Add No Activity,然后直接点击Finish即可。这样我们的Library就创建好了。

我想说的是为何这么做?昨天在研究的时候,因为用到了.aar作为EasyCamera的库,并没有找到合适的方法导入.aar文件,导致自己在这个问题上浪费了不少时间,所以还是选择了这样一种方式来引入,方便而且更快捷。

下边就是需要创建我们的工程Module了,在第一张图上点击Phone And Tablet Application的选项,这样一步步创建好就OK了。

然后是在工程中引入我们刚才创建的库,这个不是很麻烦的问题,请参考我的这篇文章Android Studio--引用自己创建的Library

这样基本上万事具备了,我们需要将我们下载的zip文件解压,将下图所示的三个文件拷贝到Library中的java代码位置:

EasyCamera--更简单更灵活的相机应用编写

好了这样我们就能正常引用这个EasyCamera的库了。

这时候前期准备工作正式完成。下面我们来写一个相机的实例来感受一下。

首先先附上布局文件activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
    <SurfaceView
        android:id="@+id/camera_preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        />

    <Button
        android:id="@+id/btn_capture"
        android:text="Capture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />

</LinearLayout>

布局文件很简单,不做过多解释,就是一个相机预览和拍照按钮。

然后附上MainActivity.java的代码:

import library.DefaultEasyCamera;
import library.EasyCamera;

import android.content.Context;
import android.hardware.Camera;
import android.os.Environment;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class MainActivity extends ActionBarActivity {

    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    private Button capture;


    /**
     * 判断是否在预览状态
     */
    private boolean previewIsRunning = false;

    private EasyCamera mEasyCamera;
    private EasyCamera.CameraActions mCameraActions;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSurfaceView = (SurfaceView) findViewById(R.id.camera_preview);
        capture = (Button) findViewById(R.id.btn_capture);
        mSurfaceHolder = mSurfaceView.getHolder();

        mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                // 开启后置摄像头
                mEasyCamera = DefaultEasyCamera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                // 设置相机翻转角度
                //  mEasyCamera.setDisplayOrientation(90);
                // 正常显示相机预览
                WindowManager manager = (WindowManager) MainActivity
                        .this.getSystemService(Context.WINDOW_SERVICE);
                mEasyCamera.alignCameraAndDisplayOrientation(manager);
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                if(!previewIsRunning && mEasyCamera != null) {
                    try {
                        // 开启预览
                        mCameraActions =  mEasyCamera.startPreview(holder);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    previewIsRunning = true;
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                // 停止预览并释放
                mEasyCamera.stopPreview();
                mEasyCamera = null;
            }
        });

        capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EasyCamera.PictureCallback mPictureCallback = new EasyCamera.PictureCallback(){

                    @Override
                    public void onPictureTaken(byte[] data, EasyCamera.CameraActions actions) {
                        // 停止预览
                        mEasyCamera.stopPreview();
                        try {
                            // 延时1000s,看的更加清楚
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 存储图片的操作
                        FileOutputStream fos = null;
                        try {
                            Log.d("TAG",getExternalFilesDir(Environment.DIRECTORY_PICTURES)+File.separator+"abc.jpg");
                            fos = new FileOutputStream(new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES)
<span style="white-space:pre">				</span>+File.separator+"abc.jpg"));
                            fos.write(data);
                            fos.close();
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        // 开启预览
                        EasyCamera.Callbacks.create().withRestartPreviewAfterCallbacks(true);
                        try {
                            mEasyCamera.startPreview(mSurfaceHolder);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                };
                // 拍摄照片的操作
                mCameraActions.takePicture(
                        EasyCamera.Callbacks.create().withJpegCallback(mPictureCallback));

            }
        });

    }
}

最后的话需要我们把相应的permission加上,但是我们可以把这个权限加载Library中,这样我们的工程就不需要添加了!权限如下:

<uses-permission android:name=”android.permission.CAMERA”/>
    <uses-feature android:name=”android.hardware.camera” android:required=”false”/>

好了,这样我们来看一下运行效果,

EasyCamera--更简单更灵活的相机应用编写

中间发生了一个小错误,就是在运行时点击中间的home键退出时,再次进入程序发生了崩溃的现象,深入查看代码的时候,是自己释放相机的时候考虑的不够周全,现在对于自己的代码做出这样的修改:

 <span style="white-space:pre">	</span>@Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d("TAG","surfaceDestroyed停止并释放");
                // 停止预览并释放
                mEasyCamera.stopPreview();
                mEasyCamera.release();
                mEasyCamera = null;
                mCameraActions = null;
                previewIsRunning = false;
            }

而且在代码头部mEasyCamera = null,这样修改后,问题就不大了。在修改的过程中,你可能会发现,没有Camera的release的相应代码,这样我们就修改下源代码了。

首先我们在EasyCamera接口中添加release方法,如下:

    /**
     * 释放相机的方法
     */
    void release();

然后在DefaultCamera中来实现这个方法:

    @Override
    public void release() {
        camera.release();
    }

这样简单的一修改我们就可以在自己的代码中将相机完美的释放了!

怎么样是不是很简单啊?

这里附上我的源代码下载地址

参考文章:http://techblog.bozho.net/fixing-the-android-camera-api/ 英文好的朋友可以直接过来读!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/38945.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注