Surfaceview调用Camera实现拍照

本文详细介绍了如何利用Surfaceview调用Camera实现拍照功能,包括Surfaceview的使用步骤、拍照功能的实现思路及关键代码,同时强调了SurfaceHolder.Callback的注意事项和相机资源的释放。此外,作者分享了对编程行业的感悟,提倡真正的勤奋和持续的学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Surfaceview的使用

       surfaceView的使用主要有三步:继承SurfaceView;获取SurfaceViewHolder;应用Holder更新展示内容。Surfaceview的应用有常用类型及数据展示的Demo。

       拍照功能实现思路:

<span style="font-size:18px;">1,依据布局,获取Surfaceview对象;

2,获取Holder对象并设置属性;

3,绑定SurfaceHolder.Callback回调接口;

4,回调接口的surfaceCreated方法中设置Camera并设置对应属性;

5,设置拍照点击事件,在监听事件中绑定Camera.PictureCallback回调监听;

6,PictureCallback监听中依据回调数据,进行结果保存。【保存照片并展示】</span>

      

二、实现拍照功能

        activity_take_pic.xml:

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

    <SurfaceView
        android:id="@+id/surfaceView_2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible" />

    <ImageView
        android:id="@+id/pic_pre_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />

    <Button
        android:id="@+id/take_pic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:background="@mipmap/camera_canon"
        android:text="拍照" />

</FrameLayout>
        TakePictureActivity.java主类实现:

public class TakePictureActivity extends Activity {
    /**
     * 图片预览及展示
     */
    private SurfaceView surfaceView;
    /**
     * 拍照
     */
    private Button takePic;
    /**
     * 图片展示
     */
    private ImageView preViewPic;
    /**
     * 调用系统相机
     */
    private Camera camera;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_take_pic);
        /**
         * 窗口布满全局
         */
        getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        initView();
        initListener();
    }

    /**
     * 初始化View
     */
    private void initView() {
        surfaceView = (SurfaceView) findViewById(R.id.surfaceView_2);
        takePic = (Button) findViewById(R.id.take_pic);
        preViewPic = (ImageView) findViewById(R.id.pic_pre_view);
    }

    /**
     * 初始化监听器
     */
    private void initListener() {
        SurfaceHolder holder = surfaceView.getHolder();
        holder.setFixedSize(176, 155);
        holder.setKeepScreenOn(true);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        holder.addCallback(new TakePictureSurfaceCallback());

        takePic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (camera != null) {
                    camera.takePicture(null, null, new TakePictureCallback());
                }
            }
        });
    }


    private final class TakePictureSurfaceCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera = Camera.open();
                if (camera == null) {
                    int cametacount = Camera.getNumberOfCameras();
                    camera = Camera.open(cametacount - 1);
                }

                Camera.Parameters params = camera.getParameters();
                params.setJpegQuality(80);//照片质量
                params.setPictureSize(1024, 768);//图片分辨率
                params.setPreviewFrameRate(5);//预览帧率

                camera.setDisplayOrientation(90);
                /**
                 * 设置预显示
                 */
<span style="color:#FF0000;">//                camera.setPreviewDisplay(surfaceView.getHolder());
                camera.setPreviewDisplay(holder);</span>
                camera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {

                    }
                });
                /**
                 * 开启预览
                 */
                camera.startPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (camera != null) {
                camera.release();
                camera = null;
            }
        }
    }


    private final class TakePictureCallback implements Camera.PictureCallback {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            ByteArrayOutputStream os = new ByteArrayOutputStream(data.length);
            byte[] tempData = os.toByteArray();
            if (tempData != null && tempData.length > 0) {
                Bitmap bitmap = BitmapFactory.decodeByteArray(tempData, 0, tempData.length);
                preViewPic.setVisibility(View.VISIBLE);
                surfaceView.setVisibility(View.GONE);
                preViewPic.setImageBitmap(bitmap);
            }
        }
    }
}
展示效果:



三、细节注意

1,SurfaceHolder.Callback的surfaceCreated方法中,holder使用传参即可;

2,Camera在使用后必须camera.release();释放相机资源。

这里是源码


您也可以看看:Surfaceview的应用~_~



       代码前行的路上还有些许枯燥,我愿意倾听您的声音,也希望您的帮助能更多的优化自己。我还没有爱上这个行业,我尽可能的保持一种好习惯,我相信能力增强的路上给我更多绚丽,一定会让我爱上这个行业的。现在的我只是及格,在及格边上徘徊。我处于迷茫中,暂时找不到出口 #_# ||     就多积累点。。。。。


“真正的勤奋,不是被迫的机械重复劳动,也不是自我感动式的摧残健康,更不是因为

拖延症导致的最后一刻效率爆发。它来自于一个人内心深处,对与那些无法获得即刻回

报的事情,依然能够保持十年如一的热情与专注。”




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壹叁零壹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值