这里有新鲜出炉的精品教程,程序狗速度看过来!
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。
这篇文章主要介绍了Android 自定义相机及分析源码的相关资料,这里自定义相机并使用系统相机教程源码进行详解,需要的朋友可以参考下
Android 自定义相机及分析源码
使用Android 系统相机的方法:
要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下
- <intent-filter>
- <action android:name="android.intent.action.IMAGE_CAPTURE" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
action的作用就是声明action的类型,便于Intent的使用,category的作用就是注册,没有它。相关操作将不起作用。
一种方式是简单粗暴的实现,如下
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- startActivityForResult(intent, REQ_1);
- //然后在 onActivityResult方法中实现数据的获取,此处是展示在了一个ImageView上
- if (resultCode == RESULT_OK) {
- if (requestCode == REQ_1) {
- Bundle bundle = data.getExtras();
- Bitmap bitmap = (Bitmap) bundle.get("data");
- imageView.setImageBitmap(bitmap);
- }
小总结:这样的好处是简单快捷,但是在现在的android智能机中,好多相片都是很大的,这里获得的仅仅是一个缩略图罢了
另外一种方式是稍微温婉一点了,而且效果也更好一点,好处就在于它是先将照片信息存储到本地一个临时文件中,然后让ImageView去相关路径下进行读取,这样就可以获得清晰度很高的图片了。如下
- /*
- * 此方法的存在意义就是不在onActivityResult方法的data中获取我们拍照的缩略图,而是从我们的文件输出目录下直接查看原图
- * 这样的好处就是可以对大容量的照片进行便捷的准确的操作
- */
- public void onStartCarema2(View view) {
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- //见你给你路径传递回需要的处理方法中
- Uri uri = Uri.fromFile(new File(myFilePath));
- //设置文件的输出路径
- intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- startActivityForResult(intent, REQ_2);
- }
- //然后在onActivityResult方法中进行相关的处理就可以了
- else if (requestCode == REQ_2) {
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(myFilePath);
- Bitmap bitmap = BitmapFactory.decodeStream(fis);
- imageView.setImageBitmap(bitmap);
- } catch(FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } finally {
- try {
- fis.close();
- } catch(IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- //记得最后一定要关闭相关的流操作。否则会引起相关的异常的。
开发自定义的相机
由于开发自定义的相机要进行相关的权限的生命,所以一定不要忘记在清单文件中做相关的处理,如下
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.CAMERA"/>
然后有以下几个步骤:
以上就是整个思路
接下来就是使用系统Camera的代码展示
(可以直接copy相关代码块,添加到你的应用中去,实现Camera这一功能。)
首先是MainActivity
布局
- <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:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- android:orientation="vertical"
- tools:context=".MainActivity" >
- <Button
- android:id="@+id/startCarema"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="6dp"
- android:text="StartCarema"
- android:onClick="onStartCarema"
- />
- <Button
- android:id="@+id/startCarema2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="6dp"
- android:text="StartCarema2"
- android:onClick="onStartCarema2"
- />
- <Button
- android:id="@+id/customCarema"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="6dp"
- android:text="CustomCarema"
- android:onClick="onCustomCarema"
- />
- <ImageView
- android:id="@+id/imageview"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- </LinearLayout>
代码
- package com.example.camerademo;
- 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.widget.Button;
- import android.widget.ImageView;
- public class MainActivity extends Activity {
- //为下面的获取请求所用
- private static int REQ_1 = 1;
- private static int REQ_2 = 2;
- Button btn_startCareme,
- btn_startCarema2,
- btn_customCarema;
- ImageView imageView;
- //定义照片存储的路径
- private String myFilePath;@Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- btn_startCareme = (Button) findViewById(R.id.startCarema);
- btn_startCarema2 = (Button) findViewById(R.id.startCarema2);
- btn_customCarema = (Button) findViewById(R.id.customCarema);
- imageView = (ImageView) findViewById(R.id.imageview);
- //初始化不同手机的SD卡的路径
- myFilePath = Environment.getExternalStorageDirectory().getPath();
- myFilePath = myFilePath + "/" + "temperature.png";
- }
- public void onCustomCarema(View view) {
- Intent intent = new Intent(this, CustomCarema.class);
- startActivity(intent);
- }
- public void onStartCarema(View view) {
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- startActivityForResult(intent, REQ_1);
- }
- /*
- * 此方法的存在意义就是不在onActivityResult方法的data中获取我们拍照的缩略图,而是从我们的文件输出目录下直接查看原图
- * 这样的好处就是可以对大容量的照片进行便捷的准确的操作
- */
- public void onStartCarema2(View view) {
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- //见你给你路径传递回需要的处理方法中
- Uri uri = Uri.fromFile(new File(myFilePath));
- //设置文件的输出路径
- intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- startActivityForResult(intent, REQ_2);
- }
- @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 == REQ_1) {
- Bundle bundle = data.getExtras();
- Bitmap bitmap = (Bitmap) bundle.get("data");
- imageView.setImageBitmap(bitmap);
- } else if (requestCode == REQ_2) {
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(myFilePath);
- Bitmap bitmap = BitmapFactory.decodeStream(fis);
- imageView.setImageBitmap(bitmap);
- } catch(FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } finally {
- try {
- fis.close();
- } catch(IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- }
- }
接下来是自定义相机的代码
主界面布局
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <Button
- android:id="@+id/capture"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="6dp"
- android:text="Capture"
- android:onClick="onCapture"
- />
- <SurfaceView
- android:id="@+id/preview"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- </LinearLayout>
ResultActivity的布局
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="Capture Result"
- android:textSize="28dp"
- android:textColor="#BFAACD"
- android:gravity="center"
- />
- <ImageView
- android:id="@+id/picture"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="center"
- />
- </LinearLayout>
代码
首先是CustomCamera类,
- package com.example.camerademo;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import android.app.Activity;
- import android.content.Intent;
- import android.graphics.ImageFormat;
- import android.hardware.Camera;
- import android.os.Bundle;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- @SuppressWarnings("unused")
- public class CustomCarema extends Activity implements SurfaceHolder.Callback{
- private Camera myCamera;
- private SurfaceView preview;
- private SurfaceHolder myHolder; //myHolder勇于展现surfaceView的图像
- private Camera.PictureCallback myPictureCallBack=new Camera.PictureCallback() {
- @Override
- public void onPictureTaken(byte[] data, Camera arg1) {
- //将拍照得到的数据信息存储到本地
- File tempFile=new File("/sdcard/temp.png");
- try {
- FileOutputStream fos=new FileOutputStream(tempFile);
- fos.write(data);
- fos.close();
- //然后将这个照片的数据信息传送给要进行展示的Activity即可
- Intent intent=new Intent(CustomCarema.this,ResultActivity.class);
- intent.putExtra("PicturePath", tempFile.getAbsolutePath());
- startActivity(intent);
- //拍照结束之后销毁当前的Activity,进入到图片展示界面
- CustomCarema.this.finish();
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.customcarema);
- preview=(SurfaceView) findViewById(R.id.preview);
- myHolder=preview.getHolder();
- myHolder.addCallback(this);
- //实现点击屏幕自动聚焦的功能,此处并不需要拍照,故只是聚焦
- preview.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- // TODO Auto-generated method stub
- myCamera.autoFocus(null);
- }
- });
- }
- @Override
- protected void onResume() {
- super.onResume();
- if(myCamera==null){
- myCamera=getCamera();
- if(myHolder != null ){
- setStartPreview(myCamera, myHolder);
- }
- }
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- super.onPause();
- releaseCamera();
- }
- /**
- * 释放相机的资源
- */
- private void releaseCamera(){
- if(myCamera !=null ){
- myCamera.setPreviewCallback(null);
- myCamera.stopPreview();
- myCamera.release();
- myCamera=null;
- }
- }
- /**
- * 拍照的一些参数设置,点击此按钮之后会触发拍照的会掉,进而实现拍照的效果
- * @param view
- */
- public void onCapture(View view){
- Camera.Parameters parameters=myCamera.getParameters();
- //设置照片的类型
- parameters.setPictureFormat(ImageFormat.JPEG);
- parameters.setPictureSize(800, 600);
- //设置为自动聚焦
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
- //设置为自动聚焦是不够的,因为我们先得到的是最为清晰的图片,所以要在聚焦成功的时候才进行拍照
- myCamera.autoFocus(new Camera.AutoFocusCallback() {
- @Override
- public void onAutoFocus(boolean success, Camera camera) {
- // TODO Auto-generated method stub
- if(success){
- myCamera.takePicture(null, null, myPictureCallBack);
- }
- }
- });
- }
- /**
- * 获取系统的一个Camera对象
- */
- private Camera getCamera(){
- Camera camera=null;
- try{
- camera=Camera.open();
- }catch(Exception e){
- e.printStackTrace();
- }
- return camera;
- }
- /**
- * 开始预览相机的内容,其实就是讲surfaceHolder与之绑定
- */
- private void setStartPreview(Camera camera,SurfaceHolder holder){
- //直接调用系统方式绑定预览
- try {
- camera.setPreviewDisplay(holder);
- //由于系统默认使用横屏预览,,所以要进行设置
- camera.setDisplayOrientation(90);
- camera.startPreview();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int arg1, int arg2, int arg3) {
- // TODO Auto-generated method stub
- myCamera.stopPreview();
- setStartPreview(myCamera, myHolder);
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- // TODO Auto-generated method stub
- setStartPreview(myCamera, myHolder);
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder arg0) {
- // TODO Auto-generated method stub
- releaseCamera();
- }
- }
然后是结果界面代码:
- package com.example.camerademo;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Matrix;
- import android.os.Bundle;
- import android.widget.ImageView;
- public class ResultActivity extends Activity {
- @Override protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.resultactivity);
- String path = getIntent().getStringExtra("PicturePath");
- ImageView imageview = (ImageView) findViewById(R.id.picture);
- //由于这样稚嫩获得横屏,所以我们要使用流的形式来转换
- // Bitmap bitmap=BitmapFactory.decodeFile(path);
- // imageview.setImageBitmap(bitmap);
- FileInputStream fis;
- try {
- fis = new FileInputStream(path);
- Bitmap bitmap = BitmapFactory.decodeStream(fis);
- Matrix matrix = new Matrix();
- matrix.setRotate(90);
- bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
- imageview.setImageBitmap(bitmap);
- } catch(FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
以上代码中已经做了下关的代码注释
总结:
安卓6.0以上版本记得加动态权限,不然会报空指针哦,还有点击拍照事件那里 别忘了加进去,不然拍照没反应
以上就是Android 自定义相机的实例详解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
来源: http://www.phperz.com/article/17/0912/345858.html