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 Camera开发系列(下)——自定义Camera实现拍照查看图片等功能的更多相关文章

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

    Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一 ...

  2. Android 快速开发系列 打造万能的ListView GridView 适配器

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...

  3. Android商城开发系列(四)——butterknife的使用

    在上一篇博客:Android商城开发系列(三)——使用Fragment+RadioButton实现商城底部导航栏实现商城的底部导航栏时,里面用到了butterknife,今天来讲解一下的butterk ...

  4. Android GIS开发系列-- 入门季(14)FeatureLayer之范围查询

    Android GIS开发系列-- 入门季(5),这篇文章中,我们知道如何去查找要素.现在有一个需求,查找某点5000米范围的要素,那如何来做呢?首先我们需要在地图上画个5000米半径的圆,然后根据Q ...

  5. Android应用开发按下返回键退向后台执行

    转载请注明来源:http://blog.csdn.net/kjunchen/article/details/50429694 Android应用开发按下返回键退向后台执行 我们日常使用的非常多Andr ...

  6. Android开发系列(二十二):AdapterViewFlipper的功能和使用方法

    AdapterViewFlipper继承了AdapterViewAnimator,它会显示一个View组件,能够通过showPrevious()和showNext()方法控制组件显示上一个.下一个组件 ...

  7. Android调用系统相机、自定义相机、处理大图片

    Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理 ...

  8. Android Studio开发基础之自定义View组件

    一般情况下,不直接使用View和ViewGroup类,而是使用使用其子类.例如要显示一张图片可以用View类的子类ImageView,开发自定义View组件可分为两个主要步骤: 一.创建一个继承自an ...

  9. Android快速开发系列 10个常用工具类

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅 ...

随机推荐

  1. 计算机网络中的TCP/IP模型

    Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议.Inter ...

  2. 14 Fragment 注意点

    API 过时问题 API 23过时 public void onAttach(Activity activity)替换为public void onAttach(Context context) 注意 ...

  3. ceil和floor函数的编程实践

    ceil()向上取整 floor向下取整 题目 在最近几场魔兽争霸赛中,赫柏对自己的表现都不满意. 为了尽快提升战力,赫柏来到了雷鸣交易行并找到了幻兽师格丽,打算让格丽为自己的七阶幻兽升星. 经过漫长 ...

  4. SSH深度历险(六) 深入浅出----- Spring事务配置的五种方式

    这对时间在学习SSH中Spring架构,Spring的事务配置做了详细总结,在此之间对Spring的事务配置只是停留在听说的阶段,总结一下,整体把控,通过这次的学习发觉Spring的事务配置只要把思路 ...

  5. ROS(indigo)swarm_robot 群机器人示例Gazebo

    ROS(indigo)swarm_robot 群机器人示例Gazebo 参考网址:https://github.com/yangliu28/swarm_robot_ros_sim 安装提示:catki ...

  6. 【如何快速的开发一个简单的iOS直播app】(代码篇)

    开篇([如何快速的开发一个完整的iOS直播app](原理篇)) 好久没写简书,因为好奇的我跑去学习直播了,今天就分享一下我的感慨. 目前为止直播还是比较热点的技术的,简书,git上有几篇阅读量和含金量 ...

  7. 【unix网络编程第三版】ubuntu端口占用问题

    <unix网络编程>一书中的代码并不是能直接运行,有时候需要结合各方面的知识来解决,大家在这本书的时候,一定要把代码都跑通,不难你会错过很多学习的机会! 1.问题描述 本人在阅读<U ...

  8. zookeeper学习总结

    最近一两天,一直在看zookeeper,自己也感觉头昏脑涨的. 现记录一下,最近的所得: 安装与配置: http://blog.csdn.net/morning99/article/details/4 ...

  9. JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口

    JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一. ...

  10. Leetcode_160_Intersection of Two Linked Lists

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41593747 Intersection of Two Li ...