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. 深度学习&机器学习资源汇总1

    本篇博客的目地,是对工作学习过程中所遇所见的一些有关深度学习.机器学习的优质资源,作分类汇总,方便自己查阅,也方便他人学习借用. 主要会涉及一些优质的理论书籍和论文.一些实惠好用的工具库和开源库.一些 ...

  2. Swift中不用桥接文件和.h头文件直接和C代码交互的方法

    我们知道一般情况下Swit要想调用obj-c,c或c++代码必须通过obj-c以及桥接文件才可以办到,但是对于某些简单的代码,我们可以跳过桥接文件和.h头文件,直接和C代码交互呢! 我们再Projec ...

  3. require.js使用步骤

    以superagent为例 1.设置lib目录 requirejs.config({ baseUrl: 'libs' }); 2. 使用SuperAgent require(['superagent' ...

  4. Android简易实战教程--第二十六话《网络图片查看器在本地缓存》

    本篇接第二十五话  点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52389856 上一篇已经把王略中的图片获取到了.生活中有这么 ...

  5. 2.5、Android Studio添加多适配的向量图片

    Android Studio包含一个Vector Asset Studio的工具,可以帮助你添加Material图标和导入SVG(Scalable Vector Graphic)文件到你的项目中作为向 ...

  6. TDD实践感悟

    每个开发者都想开发出高质量的代码,更少的Bug.更容易维护不仅让人心情愉悦,也让我们有更多时间去学习和生活. 少加一些班,多陪家人,:) 当开发任务非常简单时,比如基本的增删改查,可能使用怎样的方式开 ...

  7. 错误 frm-40654 记录已经被另一个用户更新,重新查询以查看修改

     导致这问题的原因有多个,有些是最近在项目上发现不同于网上其他人遇到的 网上一般来说大家都说有如下几个原因.但是在项目上做返利时 对AP invoice 的有做更改,导致更改或插入的数据在界面上修 ...

  8. Get and Post(Unity3D开发之六)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=565 unity3d中的www直 ...

  9. ROS_Kinetic_13 ROS数据录制与回放

    ROS_Kinetic_13 ROS数据录制与回放 官网教程:http://wiki.ros.org/cn/ROS/Tutorials/Recording%20and%20playing%20back ...

  10. TOMCAT数据源连接配置

    /* *本文档简单介绍系统使用TOMCAT6.0数据源方式连接数据库的配置方法: *1,系统环境:  gdczsam4.0 + Tomcat6.0 + JDK1.5 + SQL Server2008 ...