zoukankan      html  css  js  c++  java
  • 学习Android的Camera 2015-06-12 21:15 21人阅读 评论(0) 收藏

    相机类是用于设置图像捕捉设置,开始/停止预览,拍照片,检索视频帧进行编码.这个类是相机的客户服务,负责管理实际的相机硬件

    相机的工作流程:

    景物(SCENE)通过镜头(LENS)生成的光学图像投射到图像传感器(Sensor)表面上,然后转为电信号,经过A/D(模数转换)转换后变为数字图像信号,再送到数字信号处理芯片(DSP)中加工处理,再通过IO接口传输到CPU中处理,通过DISPLAY就可以看到图像了

    一:指定路径图片,存储路径

    1.Intent intent =new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    2.设置图片保存路径

    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,uri);

    3.启动相机进行拍照

    startActivityForResult(intent,100);//这个数可以随便起.


    二:不指定图片存储路径

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    启动相机进行拍照:startActivityForResult(intent, 100);

    重写onActivityResult(int reqCode,int resultCode,Intent data)方法获取图片


    图片二次采样的意思:

    通过字节数组或者流,只去加载图片的外边缘,此时必须指定BitmapFactory.Options的inJustDecodeBounds成员名,将其只为true,一旦设置为true,BitmapFactory解码后返回值为null,通过Options的outHeight和outWeigh可以获得图片的宽高,然后根据大小指定合适的缩放比例,通过Options.inSampleSize,大大降低加载图片导致内存溢出的风险

    BitmapFactory.Options 图片处理的选项类

    一次采样只取图片的边缘:Options.inJustDecodeBounds=true

    对SDCard中的图片一次采样:BitmapFactory.decodeFile(String path,Options opts)

    Options.outWidth 原始图片的宽度

    Options.outHeight 原始图片高度

    设置图片的缩放比例:Options.inSampleSize,默认为1,即原始大小

    根据待显示的图片大小,获取合适的缩放比例

    二次采样前取消一次只采样边缘的属性: Options.inJustDecodeBounds=false

    二次采样:BitmapFactory.decodeFile(String path,Options opts)

    ** 
     * 根据图片字节数组,对图片可能进行二次采样,不致于加载过大图片出现内存溢出 
     * @param bytes 
     * @return 
     */  
    public static Bitmap getBitmapByBytes(byte[] bytes){  
          
        //对于图片的二次采样,主要得到图片的宽与高  
        int width = 0;  
        int height = 0;  
        int sampleSize = 1; //默认缩放为1  
        BitmapFactory.Options options = new BitmapFactory.Options();  
        options.inJustDecodeBounds = true;  //仅仅解码边缘区域  
        //如果指定了inJustDecodeBounds,decodeByteArray将返回为空  
        BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);  
        //得到宽与高  
        height = options.outHeight;  
        width = options.outWidth;  
      
        //图片实际的宽与高,根据默认最大大小值,得到图片实际的缩放比例  
        while ((height / sampleSize > Cache.IMAGE_MAX_HEIGHT)  
                || (width / sampleSize > Cache.IMAGE_MAX_WIDTH)) {  
            sampleSize *= 2;  
        }  
      
        //不再只加载图片实际边缘  
        options.inJustDecodeBounds = false;  
        //并且制定缩放比例  
        options.inSampleSize = sampleSize;  
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);  
    }  

    自定义相机

    获取SurfaceHolder的对象设置Surface的分辨率,类型以及SurfaceHolder.Callback的回调

    surfaceCreated

    1.   Camera.open()打开相机

    2.    setPreviewDisplay(SurfaceHolder holder)设置使用哪个SurfaceView来显示取得的图片

    3.   Camera.startPreview()预览取景

    4.   Camera的takePicture()方法进行拍照,添加PictureCallback()回调,保存数据到sd卡

    surfaceChanged:设置照相机的参数,2.3.3以后不需要设置

    surfaceDestroyed

    1.   camera.stopPreview()

    2  .camera.release()

    3.   camera = null


     <!--往sdcard中写入数据的权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
     <!--在sdcard中创建/删除文件的权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

    下面是Demo

    public class MainActivity extends Activity implements OnClickListener {
    	private SurfaceView surfaceView;
    	private Button btn_pic;
    	private Button btn_look;
    	private SurfaceHolder surfaceHolder;
    	private Camera camera;
    String path;
    	@SuppressWarnings("deprecation")
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		surfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
    		// 获取surfaceView的操作类surfaceHolder
    		surfaceHolder = surfaceView.getHolder();
    		// 由camera提供图像数据,这样显示比较流畅
    		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    		// 设置Surface分辨率
    		surfaceHolder.setFixedSize(176, 144);
    		// 设置屏幕常亮
    		surfaceHolder.setKeepScreenOn(true);
    		surfaceHolder.addCallback(new Callback() {
    
    			@Override
    			public void surfaceDestroyed(SurfaceHolder arg0) {
    				// TODO Auto-generated method stub
    				<span style="BACKGROUND-COLOR: #33ffff">if <span style="color:#ff0000;">(!</span>camera != null) {
    </span>					camera.release();
    					camera = null;
    				}
    			}
    
    			@Override
    			public void surfaceCreated(SurfaceHolder arg0) {
    				// TODO Auto-generated method stub
    				// 打开你的摄像头
    				camera = Camera.open();
    				try {
    					camera.setPreviewDisplay(arg0);
    					// camera.setDisplayOrientation(arg0);
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				// 开始预览
    				camera.startPreview();
    			}
    
    			@Override
    			public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
    					int arg3) {
    				// TODO Auto-generated method stub
    				// 获取相机各项参数的设置
    				Parameters parameters = camera.getParameters();
    				parameters.setPictureFormat(PixelFormat.JPEG);// 图片格式(图片像素存储格式)
    				parameters.setPreviewSize(arg1, arg2);// 设置预览的图片大小
    				parameters.setPictureSize(arg1, arg2);// 保存图片的大小
    				parameters.setJpegQuality(100);// 图片质量
    
    			}
    		});
    		btn_pic = (Button) findViewById(R.id.button1);
    		btn_look = (Button) findViewById(R.id.button2);
    		btn_look.setOnClickListener(this);
    		btn_pic.setOnClickListener(this);
    
    	}
    
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.main, menu);
    		return true;
    	}
    
    	@Override
    	public void onClick(View arg0) {
    		// TODO Auto-generated method stub
    		switch (arg0.getId()) {
    		case R.id.button1:
    			camera.takePicture(null, null, new PictureCallback() {
    
    				@Override
    				public void onPictureTaken(byte[] arg0, Camera arg1) {
    					// TODO Auto-generated method stub
    					// 回调接口传回的图片数据为字节码数组
    					// 把字节码直接读取为Bitmap或者进行文件存储进行显示
    					if (Environment.getExternalStorageState().equals(
    							Environment.MEDIA_MOUNTED)) {
    						File f = new File(Environment
    								.getExternalStorageDirectory() + "/sssss");
    						if (!f.exists()) {
    							f.mkdirs();
    						}
    						File f1 = new File(f, System.currentTimeMillis()
    								+ ".jpg");
    						FileOutputStream outputStream;
    						try {
    							outputStream = new FileOutputStream(f1);
    							outputStream.write(arg0);
    							outputStream.close();
    						} catch (Exception e) {
    							// TODO Auto-generated catch block
    							e.printStackTrace();
    						}
    						path = f1.getAbsolutePath();
    						Log.e("======", "====" + f1.getAbsolutePath());
    					}
    
    				}
    			});
    			break;
    		case R.id.button2:
    			Intent intent = new Intent(MainActivity.this,ShowActivity.class);
    			intent.putExtra("path", path);
    			startActivity(intent);
    			break;
    
    		default:
    			break;
    		}
    	}
    
    显示图片的activity

    public class ShowActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	// TODO Auto-generated method stub
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.activity_show);
    	ImageView img = (ImageView) findViewById(R.id.imageView1);
    	String path = getIntent().getStringExtra("path");
    	img.setImageBitmap(BitmapFactory.decodeFile(path));
    }














    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    AngularJS Insert Update Delete Using PHP MySQL
    Simple task manager application using AngularJS PHP MySQL
    AngularJS MySQL and Bootstrap Shopping List Tutorial
    Starting out with Node.js and AngularJS
    AngularJS CRUD Example with PHP, MySQL and Material Design
    How to install KVM on Fedora 22
    Fake_AP模式下的Easy-Creds浅析
    河南公务员写古文辞职信
    AI
    政协委员:最大愿望是让小学生步行上学
  • 原文地址:https://www.cnblogs.com/merbn/p/4638867.html
Copyright © 2011-2022 走看看