关闭

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

标签: androidapi图片谷歌
6596人阅读 评论(5) 收藏 举报
分类:

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

3
2
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Android自定义Camera最佳入门实例

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

android自定义相机拍照

android自定义相机拍照
  • androidzsp
  • androidzsp
  • 2017-10-17 09:32
  • 557

android实现自定义相机效果

楼主在进行android开发时用到了自定义摄像头拍照并将所拍摄的照片转化成二进制流输出这一功能(当然程序里也附带将图片存储在sd卡里的功能),花了好多天的时间查了很多资料最后终于把它给搞出来了。。。 ...
  • caicai1hao
  • caicai1hao
  • 2017-05-12 15:38
  • 702

android 自定义照相机

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

Android自定义相机超详细讲解

Android自定义相机超详细讲解 转载请标明出处: http://blog.csdn.net/vinicolor/article/details/49642861; 由于网上关于An...
  • u011277123
  • u011277123
  • 2016-11-10 16:30
  • 4288

Android 自定义Camera(一)

公司一直在做一款好玩的应用名叫Funny, 是一个以萌和可爱为主的图片社区,P图工具(欢迎大家下载玩耍哈),刚开始调用的相机是调用系统的相机, 这肯定不能满足一款应用的需求,So我开始了从零的自定义相...
  • CoderYue
  • CoderYue
  • 2016-03-18 22:39
  • 3963

Android Camera+SurfaceView实现自定义拍照

对Activity强制横屏,保证预览方向正确。使用OrientationEventListener监听设备方向,判断竖拍时,旋转照片后再保存,保证竖拍时预览图片和保存后的图片方向一致。       运...
  • u012964281
  • u012964281
  • 2014-11-15 09:55
  • 5022

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

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

适配android 7的自定义相机的预览及拍照

import android.Manifest; import android.app.Activity; import android.content.Context; import android...
  • chengjiamei
  • chengjiamei
  • 2017-02-06 18:34
  • 2338

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

第一种方式,通过按拍照键实现PictureCallback接口的方式来拍照。这种方式是非常普遍的,网上也存在很多Demo。当遇到红米手机时,照片的尺寸变成了176x144,很小很模糊,而天语的尺寸则是...
  • u010069940
  • u010069940
  • 2016-05-23 16:53
  • 3300
    个人资料
    • 访问:1080812次
    • 积分:13712
    • 等级:
    • 排名:第1079名
    • 原创:215篇
    • 转载:1篇
    • 译文:0篇
    • 评论:922条
    和我一起
    博客专栏
    文章分类