Android自定义简易照相机

不多说,上代码,有注释。

一、开权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.devin.camerademo">

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/record_app_icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        <activity android:name=".MainActivity"
            android:screenOrientation="landscape"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

二、布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <SurfaceView
        android:id="@+id/sfv_preview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

    <LinearLayout
        android:id="@+id/ll_bottom_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|center_vertical"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/btn_record"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/rec" />

    </LinearLayout>

</FrameLayout>

三、MainActivity.java源代码

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,
        Camera.AutoFocusCallback,
        Camera.PictureCallback {

    @Bind(R.id.sfv_preview)
    SurfaceView surfaceView;//预览窗口
    @Bind(R.id.btn_record)
    ImageView btnRecord;//拍照按钮

    private Camera camera=null;//相机
    private SurfaceHolder holder;//SurfaceView控制器
    private int scnWidth,scnHeight;//屏幕宽高

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置全屏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initView();
    }

    /**
     * 初始化
     */
    private void initView() {
        holder=surfaceView.getHolder();
        holder.setKeepScreenOn(true);//设置常亮,没有好像也行
        holder.addCallback(this);//添加回调,监控SurfaceView
        //获取屏幕宽高
        WindowManager manager= (WindowManager) getSystemService(WINDOW_SERVICE);
        DisplayMetrics metrics=new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        scnWidth = metrics.widthPixels;
        scnHeight = metrics.heightPixels;
        holder.setFixedSize(scnWidth, scnHeight);//录制区域的尺寸
    }

    /**
     * 点击事件
     */
    @OnClick({R.id.btn_record})
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_record:
                capture();//开始拍照
                break;
            default:break;
        }
    }

    /**
     * 拍照
     */
    private void capture(){
        Camera.Parameters parameters=camera.getParameters();//获得相机的参数
        parameters.setPictureFormat(ImageFormat.JPEG);//设置照片格式
        parameters.setPreviewSize(scnWidth,scnHeight);//设置预览尺寸
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//设置对焦模式
        camera.autoFocus(this);//开始对焦
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (camera==null){
            camera=getCamera();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }

    /**
     * 获取相机
     * @return
     */
    private Camera getCamera(){
        return Camera.open();
    }

    /**
     * 开始预览
     */
    private void startPreview(Camera camera,SurfaceHolder holder){
        try {
            camera.setPreviewDisplay(holder);//设置预览窗口
//            camera.setDisplayOrientation(90);//旋转镜头
            camera.startPreview();//开始预览
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放资源
     */
    public void releaseCamera(){
        if (camera!=null){
            camera.setPreviewCallback(null);//取消回调
            camera.stopPreview();//停止预览
            camera.release();//释放资源
            camera=null;//清除对象
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        startPreview(camera,holder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        camera.stopPreview();
        startPreview(camera,holder);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }

    /**
     * 自动对焦回调
     * @param success
     * @param camera
     */
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        if(success){
            camera.takePicture(null,null,this);
        }
    }

    /**
     * 获取图片数据回调
     * @param data
     * @param camera
     */
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File savePath = Environment.getExternalStorageDirectory();
        String saveFileName = "Capture" + System.currentTimeMillis() + ".jpg";
        File saveFile = new File(savePath, saveFileName);
        FileOutputStream fos=null;
        try {
            fos=new FileOutputStream(saveFile);
            fos.write(data);//写入数据
            fos.flush();
            Toast.makeText(this, "照片已保存在"+saveFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
            camera.stopPreview();
            camera.startPreview();//重新进入预览状态
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fos!=null){
                try {
                    fos.close();//关闭输出流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

注意:Camera的包是硬件包,不是图形包

import android.hardware.Camera;

运行成功。

问题:像素比有问题。预览图像和拍照得到的图像不一致。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值