Android相机应用开发实例

   在学习直接调用本地相机获取照片之前,我想最好还是根据Android给的相机API自己开发一个简单的相机,对于相机的运作过程有一个基本的了解。

  第一步,建立SurfaceView显示预览(拍照之前)

  activity_main.xml文件定义FrameLayout布局,用一个button来实施拍照行为

  

<FrameLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
    >

    <SurfaceView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/surfaceView"
        android:layout_gravity="center" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible"
        android:id="@+id/shot_button_layout"
        >
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:text="@string/shot"
            android:layout_marginRight="10dp"
            android:layout_marginBottom="10dp"/>

        </RelativeLayout>
</FrameLayout>

  onCreate方法布局全屏和添加回调函数,其中的button点击动作为拍摄照片

@Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE); //此方法必须在super.onCreate方法之前调用
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏显示

        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCamera.takePicture(null, null, new MyPictureCallback());
            }
        });

        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        //获取手机分辨率
        Display display = getWindowManager().getDefaultDisplay(); //Activity#getWindowManager()
        Point size = new Point();
        display.getSize(size);
        mSurfaceView.getHolder().setFixedSize(size.x,size.y);

        mSurfaceView.getHolder().setKeepScreenOn(true);
        mSurfaceView.getHolder().addCallback(new SurfaceCallback());
    }

  重要的一个步骤就是处理SurfaceView的显示与更新。

private final class SurfaceCallback implements SurfaceHolder.Callback{
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            mCamera = Camera.open();
            Camera.Parameters parameters = mCamera.getParameters();
            mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
            Camera.Size mPreviewSize = mSupportedPreviewSizes.get(mSupportedPreviewSizes.size()-1);

            parameters.setPreviewSize(mPreviewSize.width,mPreviewSize.height);

            parameters.setPreviewFrameRate(5);
            if(parameters.getSupportedPreviewFormats().contains(ImageFormat.JPEG)){
                parameters.setPreviewFormat(ImageFormat.JPEG);
            }

            parameters.setPictureFormat(ImageFormat.JPEG);
            parameters.setPictureSize(1024, 768);
            parameters.setJpegQuality(80);
            mCamera.setParameters(parameters);
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.v(LOG_TAG,"Camera parameters are: "+parameters.flatten());
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (mCamera != null){
                mCamera.release();
                mCamera =null;
            }
        }
    }

   

   第二步,实现拍照与照片数据的保存(保存在sd卡里的CameraDemo/目录下)。

private final class MyPictureCallback implements Camera.PictureCallback {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            SavePictureTask savePictureTask = new SavePictureTask();
            savePictureTask.execute(data);
            mCamera.startPreview();
        }
    }

  建立上边代码中的SavePictureTask异步处理类。

public class SavePictureTask extends AsyncTask<byte[],Void,Void>{
    @Override
    protected Void doInBackground(byte[]... params) {
        File path = new File(getSDPath()+"/CameraDemo");
        if (!path.exists()) {
            path.mkdirs();
        }
        // 创建文件
        Calendar calendar = Calendar.getInstance();
        String filename = ""+calendar.get(Calendar.YEAR)+calendar.get(Calendar.MONTH)+
                calendar.get(Calendar.DAY_OF_MONTH)+Integer.toString((int) System.currentTimeMillis()) + ".jpg";
        File picture = new File(path+"/"+filename);  //这里是全路径
        try {
            FileOutputStream out = new FileOutputStream(picture);
            out.write(params[0]);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    public String getSDPath(){
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState()
                .equals(android.os.Environment.MEDIA_MOUNTED);   //判断sd卡是否存在
        if   (sdCardExist)
        {
            sdDir = Environment.getExternalStorageDirectory();//获取跟目录
        }
        return sdDir.toString();

    }
}

  实现一个简单拍照功能的相机难度不大,但是所给API的模式还需进一步理解。这个相机的自动对焦功能实现的不是太好,有待于改进,这里就不贴代码了,以后需要深入学习的。完整代码等我更新到github上会贴出地址。

时间: 2024-08-04 02:37:19

Android相机应用开发实例的相关文章

android 百度地图开发实例(转载)

因为在我的寝室google基站定位返回的数据总是为空,所以换成百度地图,发现百度地图开发起来非常方便,提供了许多有用的工具,地图的加载速度也比google地图快许多. 为了加强记忆,写一点android 百度地图开发常用的方法. 1初始化 MapManager mBMapMan = new BMapManager(this);boolean isSuccess = mBMapMan.init(this.mStrKey, new MyGeneralListener()); isSuccess 的值

Android相机开发那些坑

版权声明:本文由王梓原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/168 来源:腾云阁 https://www.qcloud.com/community 最近我负责开发了一个跟Android相机有关的需求,新功能允许用户使用手机摄像头,快速拍摄特定尺寸(1:1或3:4)的照片,并支持在拍摄出的照片上做贴纸相关的操作.由于之前没有接触过Android相机开发,所以在整个开发过程中踩了不少坑,费了不少时间和精力.这篇文章总

组长问我几天能开发一个人见人爱的百万量级Android相机,我是这样回答的...

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由QQ空间开发团队发表于云+社区专栏 最近我负责开发了一个跟Android相机有关的需求,新功能允许用户使用手机摄像头,快速拍摄特定尺寸(1:1或3:4)的照片,并支持在拍摄出的照片上做贴纸相关的操作.由于之前没有接触过Android相机开发,所以在整个开发过程中踩了不少坑,费了不少时间和精力.这篇文章总结了Android相机开发的相关知识.流程,以及容易遇到的坑,希望能帮助今后可能会接触Android相机开发的朋友快速上手,节省时

Android手机拨打电话的开发实例

一部手机最常用的功能就是打电话和发短信了,在Android开发中我们如何通过程序拨打电话呢?本文就给出一个用Android手机拨打电话的简单的实例. 下面是开发此实例的具体步骤: 一.新建一个Android工程,命名为phoneCallDemo. 二.设计程序的界面,打开main.xml把内容修改如下: XML/HTML代码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and

Android相机开发详解(一)

Android相机开发详解(一) 请支持原创,尊重原创,转载请注明出处:http://blog.csdn.net/kangweijian(来自kangweijian的csdn博客) Android相机开发能够实现打开相机,前后摄像头切换,摄像预览,保存图片,浏览已拍照图片等相机功能. Android相机开发详解(一)主要实现打开相机,摄像预览,前后置摄像头切换,保存图片等四个功能. Android相机开发详解(二)主要实现翻页浏览相片,触控缩放浏览图片,删除图片,发送图片等四个功能. Andro

android widget 开发实例 : 桌面便签程序的实现具体解释和源代码 (上)

如有错漏请不吝拍砖指正,转载请注明出处,很感谢 桌面便签软件是android上经常使用软件的一种,比方比較早的Sticky Note,就曾很流行, Sticky Note的介绍能够參见 http://www.tompda.com/c/article/11778/ 而实际上使用android平台对widget开发的支持,桌面便签类软件是很易于开发的. 本文通过逐步实现一个简单的桌面便签软件,和大家分享进行widget开发的过程和方法. 1.MyNote的终于实现效果 为了提起大家阅读本文的兴趣,先

Android开发实例之miniTwitter登录界面的实现

原文: http://www.jizhuomi.com/android/example/134.html 本文要演示的Android开发实例是如何完成一个Android中的miniTwitter登录界面,下面将分步骤讲解怎样实现图中的界面效果,让大家都能轻松的做出美观的登录界面. miniTwitter登录界面效果图 先贴上最终要完成的效果图: miniTwitter登录界面的布局分析 首先由界面图分析布局,基本可以分为三个部分,下面分别讲解每个部分. 第一部分是一个带渐变色背景的LinearL

Android系统Google Maps开发实例浅析

Google Map(谷歌地图)是Google公司提供的电子地图服务.包括了三种视图:矢量地图.卫星图片.地形地图.对于Android系统来说,可以利用Google提供的地图服务来开发自己的一些应用.Google Map的服务体现在两个方面:地图API和位置API.使用Android Maps API(地图API)和Android Location API(定位API)可以轻松实现实用而且强大的功能. 我的位置:“我的位置”在地图上显示你的当前位置(通常在 1000 米范围之内).即使没有 GP

Android Widget 开发实例:桌面便签程序的实现详解和源码

桌面便签软件是Android上常用软件的一种,比如比较早的Sticky Note,就曾非常流行,而实际上使用android平台对widget开发的支持,桌面便签类软件是非常易于开发的. 本文通过逐步实现一个简单的桌面便签软件,和大家分享进行widget开发的过程和方法. 同时本程序提供完整的工程源码下载 免费下载地址在 http://linux.linuxidc.com/ 用户名与密码都是www.linuxidc.com 具体下载目录在 /pub/Android源码集锦/2011年/10月/An