• 学习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));
    }














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

  • 相关阅读:
    jstack使用-倒出线程堆栈
    sentos nginx安装
    阿里云主机添加云磁盘
    redis 安装并设置为开机启动服务
    curl命令使用小结[转]
    FormView控件下DropDownList是否可以绑定
    数据绑定之DataFormatString
    GridView控件RowDataBound事件中获取列字段值的几种途径 !!!
    怎么用SQL语句备份和恢复数据库?
    XtraReports 入门教程
  • 原文地址:https://www.cnblogs.com/merbn/p/4638867.html
Copyright © 2020-2023  润新知