Android中怎么自定义相机

本篇文章给大家分享的是有关Android中怎么自定义相机,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

专注于为中小企业提供成都网站建设、做网站服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业东宝免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了超过千家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

使用Android 系统相机的方法:

要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下

 
        

        
      

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();
          }
        }
      }
    }
//记得最后一定要关闭相关的流操作。否则会引起相关的异常的。

开发自定义的相机

由于开发自定义的相机要进行相关的权限的生命,所以一定不要忘记在清单文件中做相关的处理,如下


  

然后有以下几个步骤:

  • 创建Camera,并完成初始化Camera,开始预览,释放资源三个方法

  • 与Activity的SurfaceView进行绑定。

  • 在系统的onPause(),onResume()方法中进行相关状态设置

  • 对Camera进行参数设置,作用就是对照片类型和状态进行相关的设置

  • 将拍得的照片进行展示,一般会新开一个Activity,用ImageView进行承载,我们还可以在此Activity上添加TextView,实现水印效果等其他的美化操作

  • 另外,如果想加入自动聚焦的功能,就可以在SurfaceView上添加onClickListener(),对屏幕进行侦听,调用myCamera.autoFocus(null);方法即可

以上就是整个思路

接下来就是使用系统Camera的代码展示

(可以直接copy相关代码块,添加到你的应用中去,实现Camera这一功能。)

首先是MainActivity

布局



  
  
  

  

代码

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();
          }
        }
      }
    }
  }


}

接下来是自定义相机的代码

主界面布局




  

  



ResultActivity的布局



    
    

代码

首先是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();
    }


  }
}

以上就是Android中怎么自定义相机,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。


当前标题:Android中怎么自定义相机
本文地址:http://csdahua.cn/article/jegdoo.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流