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


最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一个相机,虽然相机这东西,兼容性不敢恭维,但是用到的地方确实很多,所以今天,我们就一起来学习一下吧

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

一.Camera的启动方式

1.调用系统方式

2.自定义相机

二.调用系统相机

喜闻乐见,调用系统相机是十分的简单的,我们这里演示的话,还是新建一个工程吧,这里就直接用Eclipse开发了,这里我们新建一个项目——SystemCamera

activity_main.xml

这里直接一个button就够了
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/on_camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="打开相机" />

</RelativeLayout>

MainActivity

package com.lgl.camera;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

    private Button on_camera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

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

            @Override
            public void onClick(View v) {
                /**
                 * 我们使用Intent的方式打开系统相机
                 * 1.直接跳转相机包名,前提是你知道这个应用的包名
                 * 2.就是使用隐式Intent了,在这里我们就使用隐式intent
                 */
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //指定拍照
                startActivity(intent);
            }
        });
    }
}

好的,我们来运行一下吧

三.获取拍照图片

说到获取图片,大家应该就立马想到了startActivityForResult,没错,我们就是这样直接拿到传递回来的data,然后通过Bundle转换二进制流的方式获得一个bitmap,好的,这样的话,我们就要新增加一个imageview了

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/on_camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="打开相机" />

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

</LinearLayout>

MainActivity

package com.lgl.camera;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private Button on_camera;
    private ImageView iv_photo;

    // 返回码
    private static final int CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        iv_photo = (ImageView) findViewById(R.id.iv_photo);
        on_camera = (Button) findViewById(R.id.on_camera);
        on_camera.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                /**
                 * 我们使用Intent的方式打开系统相机
                 * 1.直接跳转相机包名,前提是你知道这个应用的包名
                 * 2.就是使用隐式Intent了,在这里我们就使用隐式intent
                 */
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 指定拍照\
                // 拍照返回图片
                startActivityForResult(intent, CODE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        // 判断是否返回值
        if (resultCode == RESULT_OK) {
            // 判断返回值是否正确
            if (requestCode == CODE) {
                // 获取图片
                Bundle bundle = data.getExtras();
                // 转换图片的二进制流
                Bitmap bitmap = (Bitmap) bundle.get("data");
                // 设置图片
                iv_photo.setImageBitmap(bitmap);
            }
        }
    }
}

好,我们继续运行一下

加载大图片

这里我们要知道一个概念,就是我们返回结果是从data中取出来的,但是这个data不可能存储太多的东西,比如你拍的4K照片,动辄几十M,那不就直接挂了嘛,google是这样设定的,data返回的只是有一个缩略图,但是我们实际开发当中怎么可以使用缩略图,别急,是有办法的

我们再增加一个button和一个imageview为了显示真实大小的图片,这里就直接上完整代码了,思路十分的顺,但是我们所用到的方式是要写sd卡的,我们新增加一个权限

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

接着我们就可以在他返回请求的时候请求另一个返回码了

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/on_camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="打开相机" />

    <Button
        android:id="@+id/on_camera_big"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="大图片" />

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

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

</LinearLayout>

MainActivity

package com.lgl.camera;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private Button on_camera;
    private ImageView iv_photo;
    private Button on_camera_big;
    private ImageView iv_photo_big;

    // 返回码
    private static final int CODE = 1;
    private static final int CODEBIG = 2;

    // 记录文件保存位置
    private String mFilePath;
    private FileInputStream is = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 获取SD卡路径
        mFilePath = Environment.getExternalStorageDirectory().getPath();
        // 文件名
        mFilePath = mFilePath + "/" + "photo.png";

        iv_photo = (ImageView) findViewById(R.id.iv_photo);
        iv_photo_big = (ImageView) findViewById(R.id.iv_photo_big);
        on_camera = (Button) findViewById(R.id.on_camera);
        on_camera.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                /**
                 * 我们使用Intent的方式打开系统相机
                 * 1.直接跳转相机包名,前提是你知道这个应用的包名
                 * 2.就是使用隐式Intent了,在这里我们就使用隐式intent
                 */
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 指定拍照
                // 拍照返回图片
                startActivityForResult(intent, CODE);
            }
        });
        on_camera_big = (Button) findViewById(R.id.on_camera_big);
        on_camera_big.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 指定拍照
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                // 加载路径
                Uri uri = Uri.fromFile(new File(mFilePath));
                // 指定存储路径,这样就可以保存原图了
                intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                // 拍照返回图片
                startActivityForResult(intent, CODEBIG);

            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        // 判断是否返回值
        if (resultCode == RESULT_OK) {
            // 判断返回值是否正确
            if (requestCode == CODE) {
                // 获取图片
                Bundle bundle = data.getExtras();
                // 转换图片的二进制流
                Bitmap bitmap = (Bitmap) bundle.get("data");
                // 设置图片
                iv_photo.setImageBitmap(bitmap);
                // 加载原图
            } else if (requestCode == CODEBIG) {
                try {
                    // 获取输入流
                    is = new FileInputStream(mFilePath);
                    // 把流解析成bitmap
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    // 设置图片
                    iv_photo_big.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    // 关闭流
                    try {
                        is.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

好的,最后运行一遍

这是基本的系统相机调用,我们下篇就开始来写自定义相机的API和回调方法

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

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

  1. Android开发中如何解决加载大图片时内存溢出的问题

    Android开发中如何解决加载大图片时内存溢出的问题    在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给 ...

  2. Android -- 加载大图片到内存,从gallery获取图片,获取图片exif信息

    1. 加载大图片到内存,从gallery获取图片 android默认的最大堆栈只有16M, 图片像素太高会导致内存不足的异常, 需要将图片等比例缩小到适合手机屏幕分辨率, 再加载. 从gallery ...

  3. Android(java)学习笔记236:多媒体之加载大图片到内存(Bitmap API)

    1.Bitmap (API使用) android里面的bitmap中,一个像素点需要4个byte去表示,这是因为android表示颜色是" argb ":其中 a 表示是透明度,然 ...

  4. Android简易实战教程--第二十八话《加载大图片》

    Android系统以ARGB表示每个像素,所以每个像素占用4个字节,很容易内存溢出.假设手机内存比较小,而要去加载一张像素很高的图片的时候,就会因为内存不足导致崩溃.这种异常是无法捕获的 内存不足并不 ...

  5. Android(java)学习笔记179:多媒体之加载大图片到内存(Bitmap API)

    1. Bitmap (API使用) android里面的bitmap中,一个像素点需要4个byte去表示,这是因为android表示颜色是" argb ":其中 a 表示是透明度, ...

  6. Android学习笔记_51_转android 加载大图片防止内存溢出

    首先来还原一下堆内存溢出的错误.首先在SD卡上放一张照片,分辨率为(3776 X 2520),大小为3.88MB,是我自己用相机拍的一张照片.应用的布局很简单,一个Button一个ImageView, ...

  7. Android 加载大图片到内存

    本文演示android中图片加载到内存 首先设计界面: 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/ap ...

  8. 【Android Developers Training】 56. 更效率地加载大图片

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. Android加载大图片OOM异常解决

      尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过 ...

随机推荐

  1. linux 服务器网络有关的内核参数

    几乎所有的内核模块,包括内核核心模块和驱动程序,都在/proc/sys 文件系统下提供了某些配置文件以提供用户调整模块的属性和行为.通常一个配置文件对应一个内核参数,文件名就是参数的名字,文件的内容是 ...

  2. svn数据仓库配置,权限配置

    svn服务的开启有两种方式, ·        自带的svnserve服务(访问地址类似于svn://192.168.80.18/repos/) ·        与Apache配合使用  (访问地址 ...

  3. 21 RadioGroup ListFragment

    结构 MainActivity.java package com.qf.day21_radiogroupfragment_demo3; import java.util.ArrayList; impo ...

  4. 19 Handler 总结

    Handler 一, 回顾异步任务 AsyncTask 二, android 使用线程的规则 1,在主线程 不能做阻塞操作 2,在主线程之外的线程不能更新Ui 三, Handler的作用 1,在子线程 ...

  5. 一套强大的vim配置文件+详细注释

    phpchina折腾王独家配置,灰常牛叉的一套vim配置,另附有详细注释,自己折腾vim的时候可以参照其中的大部分设置进行一些个性化定制."是否兼容VI,compatible为兼容,noco ...

  6. 2.关于QT中的Dialog(模态窗口),文件选择器,颜色选择器,字体选择器,消息提示窗口

     1 新建一个空项目 A 编写 .pro文件 QT += gui widgets HEADERS += \ MyDialog.h SOURCES += \ MyDialog.cpp B 编写MyD ...

  7. XML之DTD(文档类型定义)

    文档类型定义(DTD)可定义合法的XML文档构建模块.它使用一系列合法的元素来定义文档的结构. DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用. 声明元素 在 DTD 中,XML 元素 ...

  8. android git上开源的项目收藏

    本文为那些不错的Android开源项目第一篇--个性化控件(View)篇,主要介绍Android上那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Ga ...

  9. (SQL Server)有关T-SQL的10个好习惯

    转自 http://www.cnblogs.com/CareySon/archive/2012/10/11/2719598.html 1.在生产环境中不要出现Select * 这一点我想大家已经是比较 ...

  10. 安卓Eclipse如何快速修改工程名及包名

    修改工程名/包名,也是我们在开发中经常遇到的问题,比如我们在开发过程中突然觉得项目名不合适,或者根包名不合适想修改一下怎么办? 如上图所示工程,我想改变一下我的项目名,如把zzz改成xxx,把我的根包 ...