Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

标签: android api 图片 谷歌
7509人阅读 评论(6) 收藏 举报
分类:

Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能


Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片

上篇讲的都是一些基本的使用,这篇就来自己定义一个相机了

参照Google API:http://developer.android.com/guide/topics/media/camera.html

我们还是在原来的demo上修改,新增一个button,点击跳转到CameraActivity,我们在CameraActivity内实现我们的自定义相机,这里值得注意的是,我们拍照时要一直捕捉拍照的过程,普通的view肯定不行,google给我们提供了一个view叫做

这里写图片描述

一.获取相机

这里有个前提,记得添加权限

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

我们新增一个方法来获取系统的相机实例

/**
     * 获取系统相机
     * 
     * @return
     */
    private Camera getcCamera() {
        Camera camera = null;
        try {
            camera = Camera.open();
        } catch (Exception e) {
            camera = null;
        }
        return camera;
    }

这里值得注意的是,camera是废弃的对象,那是因为google新给出来一个新的api

这里写图片描述

但是其实新出的api只是作为高级使用的时候才会用,一般来讲,我们还是用回以前的api

二.SurfaceView预览

要使用SurfaceView还是要

implements SurfaceHolder.Callback

activity_camera.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/sv"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <Button
        android:id="@+id/btn_camera"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="拍照" />

</LinearLayout>

预览图像

/**
     * 与SurfaceView传播图像
     */
    private void showViews(Camera camera, SurfaceHolder holder) {
        // 预览相机,绑定
        try {
            camera.setPreviewDisplay(holder);
            // 系统相机默认是横屏的,我们要旋转90°
            camera.setDisplayOrientation(90);
            // 开始预览
            camera.startPreview();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

释放占用内存

/**
     * 释放相机的内存
     */
    private void clearCamera() {

        // 释放hold资源
        if (mCamera != null) {
            // 停止预览
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            // 释放相机资源
            mCamera.release();
            mCamera = null;
        }
    }

绑定生命周期

@Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        // 在activity运行时绑定
        if (mCamera == null) {
            mCamera = getcCamera();
            if (sh != null) {
                showViews(mCamera, sh);
            }
        }
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        // activity暂停时我们释放相机内存
        clearCamera();

    }

SurfaceView回调并同步预览

@Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 开始预览
        showViews(mCamera, sh);

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // 重启功能
        mCamera.stopPreview();
        showViews(mCamera, sh);

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 释放
        clearCamera();
    }

写到这里,基本上我们的可以预览了,我们来运行一下

这里写图片描述

这里因为是模拟器,他只有前置摄像头,本应该旋转270°的,我们只要知道通过以上的方法可以同步预览影像就可以了

拍照保存图片

我们设置拍照这个button的点击事件

btn_camera = (Button) findViewById(R.id.btn_camera);
        btn_camera.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 获取当前相机参数
                Camera.Parameters parameters = mCamera.getParameters();
                // 设置相片格式
                parameters.setPictureFormat(ImageFormat.JPEG);
                // 设置预览大小
                parameters.setPreviewSize(800, 480);
                // 设置对焦方式,这里设置自动对焦
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                mCamera.autoFocus(new AutoFocusCallback() {

                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        // 判断是否对焦成功
                        if (success) {
                            // 拍照 第三个参数为拍照回调
                            mCamera.takePicture(null, null, pc);
                        }
                    }
                });

            }
        });

这里的pc是一个回调方法,我们重写

private PictureCallback pc = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // data为完整数据
            File file = new File("/sdcard/photo.png");
            // 使用流进行读写
            try {
                FileOutputStream fos = new FileOutputStream(file);
                try {
                    fos.write(data);
                    // 关闭流
                    fos.close();
                    // 查看图片
                    Intent intent = new Intent(CameraActivity.this,
                            PhotoActivity.class);
                    // 传递路径
                    intent.putExtra("path", file.getAbsolutePath());
                    startActivity(intent);
                    finish();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

查看图片

我们拍完照片然后就跳转到PhotoActivity查看图片

activity_photo.xml

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

    <TextView
        android:id="@+id/tv_path"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/iv_photo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

PhotoActivity

package com.lgl.camera;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;

public class PhotoActivity extends Activity {

    private TextView tv_path;
    private ImageView iv_photo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photo);

        String path = getIntent().getStringExtra("path");
        tv_path = (TextView) findViewById(R.id.tv_path);
        // 显示路径
        tv_path.setText(path);
        iv_photo = (ImageView) findViewById(R.id.iv_photo);

        // 调整角度
        try {
            FileInputStream fis = new FileInputStream(path);
            Bitmap bitmap = BitmapFactory.decodeStream(fis);
            // 矩阵
            Matrix matrix = new Matrix();
            matrix.setRotate(90);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), matrix, true);
            iv_photo.setImageBitmap(bitmap);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

我们运行一下
拍完之后跳转到PhotoActivity界面

这里写图片描述

但是相机是一个大坑,各种不兼容,而且还有前后置摄像头之分哟,上面代码病没有提及前置,前置需要翻转270°,并且我们之前就应该判断是否是前置,再进行旋转,这个只是初学的示例代码,有兴趣的可以下载demo玩玩

Demo下载地址:http://download.csdn.net/detail/qq_26787115/9419048

查看评论

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

本文已授权微信公众号《鸿洋》原创首发,转载请务必注明出处。 概述相机几乎是每个APP都要用到的功能,万一老板让你定制相机方不方?反正我是有点方。关于相机的两天奋斗总结免费送给你。...
  • qq_17250009
  • qq_17250009
  • 2016-10-12 11:21:58
  • 11087

android 自定义相机Camera2

上一篇文章我们已经运用Camera自定义了一个相机,今天我们就用Camera2自定义一个相机。Camera2是android5.0新增的api,Camera2与Camera差别比较大,采用了全新的模式...
  • qq_38416326
  • qq_38416326
  • 2017-05-03 16:27:17
  • 3776

android 自定义相机拍照的两种方式

第一种方式,通过按拍照键实现PictureCallback接口的方式来拍照。这种方式是非常普遍的,网上也存在很多Demo。当遇到红米手机时,照片的尺寸变成了176x144,很小很模糊,而天语的尺寸则是...
  • u010069940
  • u010069940
  • 2016-05-23 16:53:21
  • 3542

Android自定义Camera最佳入门实例

本文参考google官方api写得例子, 然后也做了一些优化, 参考地址大家请看官方camera api即可.Google官方入门实例1. 引入权限 ...
  • u013647382
  • u013647382
  • 2016-06-28 19:46:37
  • 7213

Android相机调用和自定义相机Demo源码

  • 2014年08月30日 22:10
  • 1.01MB
  • 下载

Android实现一个自定义相机的界面

我们先实现拍照按钮的圆形效果哈,Android开发中,当然可以找美工人员设计图片,然后直接拿进来,不过我们可以自己写代码实现这个效果哈,最常用的的是用layout-list实现图片的叠加,我们这个la...
  • u014427391
  • u014427391
  • 2016-04-03 18:05:05
  • 4827

android 自定义照相机

做了一个dome,内容和功能都很简单,当练练手 部分代码参考了一个博客任何自己添加了一些项目的功能,具体那个博客忘记了,不好意思。 具体就是调用系统的摄相机拍照保存到手机,以后返回相片的文件地址 效果...
  • nickey_1314
  • nickey_1314
  • 2014-12-03 14:33:58
  • 14499

Android实例讲解自定义Camera拍照和预览以及前后置摄像头切换

本博文将通过实例实现自定义Camera的功效。具体功能如下: 1.实现自定义Camera拍照; 2.实现前后置摄像头的切换; 3.实现Camera拍照后图片缩小显示以及正常预览; ...
  • lyglostangel
  • lyglostangel
  • 2016-05-20 11:14:35
  • 3996

Camera进阶,自定义拍照录像界面

Camera 官方指南,英语不太好,翻译有可能不准确,见谅 o(^▽^)o 自定义拍照,录像项目 下载地址 上一篇:初识Camera,调用系统拍照录像程序 在项目中创建一个自定...
  • krubo1
  • krubo1
  • 2016-01-08 09:18:40
  • 2117

android仿qq实现自定义拍照界面CameraView

android仿qq实现自定义拍照界面CameraView
  • pang9998
  • pang9998
  • 2016-03-26 13:10:48
  • 3896
    个人资料
    专栏达人 持之以恒 博客之星
    等级:
    访问量: 117万+
    积分: 1万+
    排名: 1029
    博客专栏
    文章分类