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. 源码推荐:移动端商城(微信小程序源代码) WebView离线缓存

    移动端商城(微信小程序源代码)(上传者:腾讯攻城师jack) 功能包括:商品橱窗,商品搜索,购物车,结账等功能. TableView嵌套webView自适应高度(上传者:linlinchen) tab ...

  2. React Native组件只Image

    不管在Android还是在ios原生的开发中,图片都是作为控件给出来的,在RN中也有这么一个控件(Image).根据官网的资料,图片分为本地静态图片,网络图片和混合app资源.一下分类介绍来源官网. ...

  3. static,this,private关键字用法

    1:成员变量和局部变量的区别(理解) (1)在类中的位置不同 成员变量:类中方法外 局部变量:方法定义中或者方法声明上 (2)在内存中的位置不同 成员变量:在堆中 局部变量:在栈中 (3)生命周期不同 ...

  4. 【移动开发】EditText输入字数限制总结(包括中文输入内存溢出的解决方法)

    限定EditText输入个数的解决方案很多,但是一般主要考虑两点,也就是处理两件事:(1)不同语言字符(英文.中文等)处理方式(2)输入字符达到数目后,是否仍然允许用户输入 第一点,涉及的东东其实蛮多 ...

  5. Android简易实战教程--第二十一话《内容观察者监听数据库变化》

    当数据库的数据发生改变,我们又想知道具体改变的情况时,就需要对数据库的变化情况做一个监控.这个任务,就由内容观察者来完成.下面这个案例,为短信数据库注册内容观察者,来监控短信的变化情况,当短信数据库发 ...

  6. 指令汇B新闻客户端开发(三) 下拉刷新

    现在我们继续这个新闻客户端的开发,今天分享的是下拉刷新的实现,我们都知道下拉刷新是一个应用很常见也很实用的功能.我这个应用是通过拉ListView来实现刷新的,先看一张刷新的原理图 从图中可知,手指移 ...

  7. Android View框架总结(八)ViewGroup事件分发机制

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52298780 上篇分析了View的事件分发流程,留了一个问题:如果上 ...

  8. Android传感器概述-android学习之旅(七)

    传感器概述 传感器是第二代智能手机的重要标志之一.现在许多的手机和平板都内置了传感器(tv除外).android的SDK支持许多的传感器有十几种,但是手机只是支持一部分.例如方向传感器(电子罗盘)和重 ...

  9. python 多进程 logging:ConcurrentLogHandler

    python 多进程 logging:ConcurrentLogHandler python的logging模块RotatingFileHandler仅仅是线程安全的,如果多进程多线程使用,推荐 Co ...

  10. java常用IO流集合用法模板

    package com.fmy; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import jav ...