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上会贴出地址。

 

你可能感兴趣的:(android)