`

(转)Android多媒体学习三:实现自己的Camera

 
阅读更多

转自chenjie19891104的的博客(http://blog.csdn.net/chenjie19891104/article/category/756236),以便以后学习和查询! 

 

Android自带的Camera应用虽然可以满足大多数情景,但是其灵活性上还有不足。但是Android允许我们定制自己的Camera。

在Android的hardware包中有一个Camera类。这个类就是获取Camera服务的,可以定制Camera等。

可以通过open()方法获取其实例。

在使用这个类是需要在AndroidManifest.xml文件中加入相应的权限和特性

 

如:

  <uses-permission android:name = "android.permission.CAMERA" />
 
<uses-feature android:name = "android.hardware.camera" />
 
<uses-feature android:name = "android.hardware.camera.autofocus" />


等。

 

本文实例:

 

package demo.camera;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.ContentValues;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;
/**
 * Android自带的Camera应用程序可以完成很多功能。但是当其不能满足我们需要的时候
 * 我们可以定制自己的Camera。Android提供了Camera类来辅助我们实现自己的Camera。
 * 这个例子就来定义一个自己的Camera
 * 首先,在Manifest中需要引入权限<uses-permission android:name="android:permission.CAMERA"/>
 * 我们需要用来存放取景器的容器,这个容器就是SurfaceView。
 * 使用SurfaceView的同时,我们还需要使用到SurfaceHolder,SurfaceHolder相当于一个监听器,可以监听
 * Surface上的变化,通过其内部类CallBack来实现。
 * 为了可以获取图片,我们需要使用Camera的takePicture方法同时我们需要实现Camera.PictureCallBack类,实现onPictureTaken方法
 * @author Administrator
 *
 */
public class MyCamera extends Activity implements SurfaceHolder.Callback,Camera.PictureCallback{
	
	public static final int MAX_WIDTH = 200;
	public static final int MAX_HEIGHT = 200;
	
	private SurfaceView surfaceView;
	
	private Camera camera; //这个是hardare的Camera对象
	
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.camera);
		surfaceView = (SurfaceView)this.findViewById(R.id.myCameraView);
		surfaceView.setFocusable(true); 
		surfaceView.setFocusableInTouchMode(true);
		surfaceView.setClickable(true);
		surfaceView.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				camera.takePicture(null, null, null, MyCamera.this);
				
			}
		});
		//SurfaceView中的getHolder方法可以获取到一个SurfaceHolder实例
		SurfaceHolder holder = surfaceView.getHolder();
		//为了实现照片预览功能,需要将SurfaceHolder的类型设置为PUSH
		//这样,画图缓存就由Camera类来管理,画图缓存是独立于Surface的
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		holder.addCallback(this);
	}
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
	}
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// 当Surface被创建的时候,该方法被调用,可以在这里实例化Camera对象
		//同时可以对Camera进行定制
		camera = Camera.open(); //获取Camera实例
	
		
		/**
		 * Camera对象中含有一个内部类Camera.Parameters.该类可以对Camera的特性进行定制
		 * 在Parameters中设置完成后,需要调用Camera.setParameters()方法,相应的设置才会生效
		 * 由于不同的设备,Camera的特性是不同的,所以在设置时,需要首先判断设备对应的特性,再加以设置
		 * 比如在调用setEffects之前最好先调用getSupportedColorEffects。如果设备不支持颜色特性,那么该方法将
		 * 返回一个null
		 */
		try {
			
			Camera.Parameters param = camera.getParameters();
			if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
				//如果是竖屏
				param.set("orientation", "portrait");
				//在2.2以上可以使用
				//camera.setDisplayOrientation(90);
			}else{
				param.set("orientation", "landscape");
				//在2.2以上可以使用
				//camera.setDisplayOrientation(0);				
			}
			//首先获取系统设备支持的所有颜色特效,有复合我们的,则设置;否则不设置
			List<String> colorEffects = param.getSupportedColorEffects();
			Iterator<String> colorItor = colorEffects.iterator();
			while(colorItor.hasNext()){
				String currColor = colorItor.next();
				if(currColor.equals(Camera.Parameters.EFFECT_SOLARIZE)){
					param.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
					break;
				}
			}
			//设置完成需要再次调用setParameter方法才能生效
			camera.setParameters(param);
			
			camera.setPreviewDisplay(holder);
			
			/**
			 * 在显示了预览后,我们有时候希望限制预览的Size
			 * 我们并不是自己指定一个SIze而是指定一个Size,然后
			 * 获取系统支持的SIZE,然后选择一个比指定SIZE小且最接近所指定SIZE的一个
			 * Camera.Size对象就是该SIZE。
			 * 
			 */
			int bestWidth = 0;
			int bestHeight = 0;
			
			List<Camera.Size> sizeList = param.getSupportedPreviewSizes();
			//如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择
			if(sizeList.size() > 1){
				Iterator<Camera.Size> itor = sizeList.iterator();
				while(itor.hasNext()){
					Camera.Size cur = itor.next();
					if(cur.width > bestWidth && cur.height>bestHeight && cur.width <MAX_WIDTH && cur.height < MAX_HEIGHT){
						bestWidth = cur.width;
						bestHeight = cur.height;
					}
				}
				if(bestWidth != 0 && bestHeight != 0){
					param.setPreviewSize(bestWidth, bestHeight);
					//这里改变了SIze后,我们还要告诉SurfaceView,否则,Surface将不会改变大小,进入Camera的图像将质量很差
					surfaceView.setLayoutParams(new LinearLayout.LayoutParams(bestWidth, bestHeight));
				}
			}
			camera.setParameters(param);
		} catch (Exception e) {
			// 如果出现异常,则释放Camera对象
			camera.release();
		}
		
		//启动预览功能
		camera.startPreview();
		
	}
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// 当Surface被销毁的时候,该方法被调用
		//在这里需要释放Camera资源
		camera.stopPreview();
		camera.release();
		
	}
	@Override
	public void onPictureTaken(byte[] data, Camera camera) {
		// data是一个原始的JPEG图像数据,
		//在这里我们可以存储图片,很显然可以采用MediaStore
		//注意保存图片后,再次调用startPreview()回到预览
		Uri imageUri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
		try {
			OutputStream os = this.getContentResolver().openOutputStream(imageUri);
			os.write(data);
			os.flush();
			os.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		camera.startPreview();
	}
	
	
	
}

 

转自chenjie19891104的的博客(http://blog.csdn.net/chenjie19891104/article/category/756236),以

便以后学习和查询!


 

 

 

学习总结:

 

1、要使用Camera,需要在Manifest.xml中添加下面三个权限

 

    <uses-permission android:name = "android.permission.CAMERA" />
    <uses-feature android:name = "android.hardware.camera" />
    <uses-feature android:name = "android.hardware.camera.autofocus" />

 

2、要使用SurfaceView存取景的容器,要用到SurfaceHolder,SurfaceHolder相当于一个监听器,
   通过其内部类SurfaceHolder.Callback来实现监听变化。


3、为了可以获取图片,我们需要使用Camera的takePicture方法同时我们需要实现Camera.PictureCallBack类,
   实现onPictureTaken方法
.
 
4、SurfaceView对象获取SurfaceHolder,并且设置SurfaceHolder的监听器


 //SurfaceView中的getHolder方法可以获取到一个SurfaceHolder实例  
 SurfaceHolder holder = surfaceView.getHolder();  
 //为了实现照片预览功能,需要将SurfaceHolder的类型设置为PUSH  
    //这样,画图缓存就由Camera类来管理,画图缓存是独立于Surface的  
 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
 //设置毁掉函数,SurfaceHolder.Callback
 holder.addCallback(this); 

 

5、Camera的一些方法
  

 camera = Camera.open(); //获取Camera实例
 //获取Camera的参数
 Camera.Parameters param = camera.getParameters();  
 
 //设置显示的大小
 param.setPreviewSize(bestWidth, bestHeight);  
 //这里改变了SIze后,我们还要告诉SurfaceView,否则,Surface将不会改变大小,进入Camera的图像将质量很差  
    surfaceView.setLayoutParams(new LinearLayout.LayoutParams(bestWidth, bestHeight));  

 
 //设置完成需要再次调用setParameter方法才能生效  
    camera.setParameters(param);  
 
 //把Camera与SurfaceHolder联系起来
 camera.setPreviewDisplay(holder);

 //如果有异常,释放掉Camera
 camera.release();  
 
  //启动预览功能  
     camera.startPreview();  
 
  //停止预览
  camera.stopPreview(); 


6、Camera.PictureCallBack是实现Camera的takePicture方法的接口


   把接口和Camera联系起来
     //Camera.PictureCallBack
    camera.takePicture(null, null, null, MyCamera.this);  

 

7、实现onPictureTaken方法


     // data是一个原始的JPEG图像数据,  
     //在这里我们可以存储图片,很显然可以采用MediaStore  
       //注意保存图片后,再次调用startPreview()回到预览  
       Uri imageUri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());  
       try {  
           OutputStream os = this.getContentResolver().openOutputStream(imageUri);  
          os.write(data);  
          os.flush();  
         os.close();  
       } catch (Exception e) {  
         // TODO: handle exception  
          e.printStackTrace();  
        }  
          
     camera.startPreview();  


  

分享到:
评论

相关推荐

    Android多媒体学习之实现自定义Camera

    Android多媒体学习之实现自定义Camera Android多媒体学习之实现自定义Camera

    Android Camera2 Demo - 实现相机预览、拍照、录制视频功能

    因为工作中要使用 Android Camera2 API 来实现相机功能,但因为Camera2比较复杂,网上资料也比较乱,有一定入门门槛,所以花了几天时间系统研究了下,这个项目就是我研究的成果。 其中包括一个自己写的Camera2的Demo...

    Android多媒体开发08-Camera框架.ppt

    Android多媒体开发08-Camera框架.ppt

    Android多媒体功能开发-使用Camera2框架拍照的例子

    Android应用使用Camera2框架拍照的例子代码。

    Android多媒体功能开发-使用Camera类拍照的例子

    Android应用中使用Camera类拍照的例子代码

    Android技术内幕.系统卷(扫描版)

    7.3 android camera 构架与实现 /375 7.3.1 android camera系统构架 /375 7.3.2 camera hal框架与实现 /377 7.3.3 camera本地实现 /385 7.4 android audio hal实现 /394 7.4.1 audio hal框架 /395 7.4.2 android默认...

    多媒体应用开发实战详解 (带目录)

    《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》Android凭借其强大的功能逐渐赢得了广大用户和开发者的青睐,已经成为移动开发平台上的翘楚。全书分为17章,分别详细讲解了Android系统基础,深入底层...

    android系统原理及开发要点详解

     9.1 Android多媒体系统的结构和业务 190  9.1.1 多媒体系统的宏观结构 190  9.1.2 多媒体的各种业务 192  9.2 多媒体系统的各个层次 199  9.2.1 libmedia的框架部分 199  9.2.2 多媒体服务 208  9.2.3 ...

    Android应用开发从入门到精通 android studio code 1-10章

     Android UI、常见控件和自定义控件、碎片、四大组件(Activity、Service、Broadcast和ContentProvider)、二维绘制、Canvas和Paint、多媒体开发等;  还讲解了Android开发的高级技术:  Camera、地图、GPS、...

    Android平台Camera基于freetype和opencv实现预览拍照支持中文水印.zip

    跨平台:OpenCV支持多种操作系统,包括但不限于Windows、Linux、macOS、Android和iOS,确保代码能够在不同平台上无缝运行。 丰富的功能:库中包含了数千个优化过的函数,涵盖了计算机视觉领域的诸多方面,如图像...

    深入Android应用开发 核心技术解析与最佳实践

    第9章全面介绍了Android的多媒体编程,包括音频、视频和Camera服务等,并对TTS的实现进行了剖析;第10章详细讲解了Android的跨语言调用;第11章深入剖析了Android的安全框架和安全机制;第12章针对商业应用的需要...

    老罗android开发视频教程全集百度网盘下载

    e /SharedPreferences/File详解 多媒体Audio/Video/Camera 详解 Android进阶高级:蓝牙/WIFI SMS/MMS 应用实现 深层次解析GPS原理,实现LocationManager/LocationProvider 进行定位/跟踪/查找/趋近警告以及...

    Android应用程序开发教程PDF电子书完整版、Android开发学习教程

    很好的电子书教程!...Android Android Android Android 学习方法 ① 了解什么是 Androi ② 建立开发环境 ③ 阅读 SDK 文档 ④ 背景知识 � Java � 面向对象 � 设计模式 � J2ME、Brew 、Symbian

    Android中的多媒体应用

    Android中的多媒体应用 音频及视频播放 迷你音乐播放器 迷你视频播放器 音视频的录制 Camera照相

    android-framework-hal

    9 Android的多媒体系统 9.1 多媒体系统的结构 应用到底层的层次结构 9.2 media核心库的结构 多媒体本地代码的结构 9.3 多媒体部分的上层代码 照相机,媒体播放,媒体录制的框架结构 9.4 PackageVideo的...

    camera.zip

    Android 多媒体开发, MediaPlayer|SoundPool | MediaRecorder | Camera2 | MediaProjectionManager ,博客地址:https://blog.csdn.net/dreams_deng/article/details/106334868

    疯狂Android讲义(第2版)源代码 第6章~第9章

    《疯狂Android讲义(第2版)》.(李刚).源代码 疯狂Android讲义目录结构: 第2章、Android应用程序界面设计,即View 2.2、布局管理(Layout):LinearLayout、TableLayout、FrameLayout、RelativeLayout; 2.3、基本...

    Android IP Camera手机版网络摄像机.rar

    一个国外的开源Android项目,android手机网络摄像机 IP Camera源代码,通过网络连接可实现远程查看拍摄内容,像一个视频监控那样,觉得挺好玩,只是代码中的注释全是英文的。本程序主要是实现两大功能,一介不间断...

    Android实例代码

    11.3、控制摄像头拍照:Camera; 第12章、OpenGL与3D应用开发 12.2、OpenGL ES基础: 12.3、绘制2D图形: 12.4、绘制3D图形: 第13章、Android的网络应用 13.1、基于TCP协议的网络通信(套接字Socket):Socket; ...

Global site tag (gtag.js) - Google Analytics