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

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

时间: 2025-01-26 22:45:58

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

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

Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一个相机,虽然相机这东西,兼容性不敢恭维,但是用到的地方确实很多,所以今天,我们就一起来学习一下吧 参照Google API:http://developer.android.com/guide/topics/media/camera.html 一.Camera的启动方式 1.调用系统方式 2.自定义

Android下 自定义Camera类如何绑定多个SurfaceView?

问题描述 Android下 自定义Camera类如何绑定多个SurfaceView? 本人正在做一个需求,需要动态地将系统相机的色彩效果显示出来,因此想要能够在多个SurfaceView中显示不同的色彩效果预览界面.各位大大如果有思路有想法还请多多赐教~

Android UI设计系列之自定义ListView仿QQ空间阻尼下拉刷新和渐变菜单栏效果(8)_Android

好久没有写有关UI的博客了,刚刚翻了一下之前的博客,最近一篇有关UI的博客:Android UI设计系列之自定义Dialog实现各种风格的对话框效果(7) ,实现各种风格效果的对话框,在那篇博客写完后由于公司封闭开发封网以及其它原因致使博客中断至今,中断这么久很是惭愧,后续我会尽量把该写的都补充出来.近来项目有个需求,要做个和QQ空间类似的菜单栏透明度渐变和下拉刷新带有阻尼回弹的效果.于是花点时间动手试了试,基本上达到了QQ空间的效果,截图如下:         通过观察QQ空间的运行效果,发现

android中不同包下的Camera有什么不一样 如图所示

问题描述 android中不同包下的Camera有什么不一样 如图所示 android中不同包下的Camera有什么不一样 如图所示 解决方案 一个可以绘制类似三维动画的,一个是相机拍照用的 解决方案二:

SharePoint 2013 图文开发系列之自定义字段

原文:SharePoint 2013 图文开发系列之自定义字段 SharePoint使用的优势,就在于开箱即用.快速搭建,SharePoint自身为我们提供了很多字段类型,已经很丰富了.但是,在实际应用中,我们还需要一些功能特殊的字段,下面,我们简单介绍下字段的开发,大家了解以后,可以按照需求扩展自己的字段类型. 1.新建项目,选择SharePoint 2013 空项目,如下图: 2.选择调试网站和解决方案类型,如下图: 3.添加新项,类,这个是用来定义字段的,如下图: 4.添加新项,类,这个是

【java开发系列】—— 自定义注解

之前在开发中,就总纳闷,为什么继承接口时,会出现@Override注解,有时候还会提示写注解@SuppressWarnings? 原来这是java特有的特性,注解! 那么什么是注解呢? 注解就是某种注解类型的一个实例,我们可以用它在某个类上进行标注,这样编译器在编译我们的文件时,会根据我们自己设定的方法来编译类. 注解都是什么呢?看下面这张图就明白了! 上面的图可以看出,注解大体上分为三种:标记注解,一般注解,元注解 @Override用于标识,该方法是继承自超类的.这样,当超类的方法修改后,实

Android UI设计系列之自定义TextView属性实现带下划线的文本框(4)_Android

在Android开发过程中,如果Android系统自带的属性不能满足我们日常开发的需求,那么就需要我们给系统控件添加额外的属性了.假如有个需求是实现带下划线的文本显示(下划线),如果不使用自定义属性的话实现起来也不太难(起码我认为的实现方式是有许多种的),今天就讲解一下如何使用自定义属性来实现上述带下划线的文本框吧.还好Android中自定义属性不是很复杂,也可以归纳为三步走吧. 老规矩,还是先贴出工程目录吧: 一.添加属性文件 在values文件夹中新建attrs.xml文件,在文件中新建属性

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

目录(?)[+] 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅助类,今天特此整理出10个基本每个项目中都会使用的工具类,用于快速开发~~ 在此感谢群里给我发项目中工具类的兄弟/姐妹~ 1.日志工具类L.java [java] view plaincopy package com.zhy.utils;      import android.u

Android软件开发之盘点自定义View界面大合集

 今天我用自己写的一个Demo 和大家详细介绍一个Android中自定义View中的使用与绘制技巧. 1.自定义view绘制字符串               相信在实际开发过程中必然很多地方都须要用到系统字 为什么会用到系统字? 方便 省内存 我相信做过J2ME游戏开发的朋友应该深知内存有多么多么重要  而且使用它还可以带来一个更重要的好处就是很方便的可以实现多国语言的切换 笔者现在在正在做的一个产品就是可以多语言切换的软件  有英语 繁体中文 等等 设想如果使用图片字的话那每个语言都须要出一