android 之 camera

由于我刚入职现在的这家公司的时候,他们对涉及到图片的比较多,所以打算写一系列图片的文章,首先就从制造图片的地方开始写起--Camera如果你的app里面只是需要拍一张照片,只需要调用系统的照相机就可以满足你的需求了通过ACTION_IMAGE_CAPTURE调用系统的照相机

intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);

然后在通过startActivityForResult方法跳转onActivityResult:

Bundle extras = data.getExtras();
Bitmap bitmap = (Bitmap) extras.get("data");
showImage.setImageBitmap(bitmap);

一般的情况下这样就满足了你的需求,也不需要增加权限,但是这里需要注意的是通过data获得的是一张缩略图,如果想获得一张原图,就需要指定图片的保存地址

Uri uri = Uri.fromFile(new File(path)); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);

同样使用startActivityForResult方法跳转onActivityResult:

FileInputStream fileInputStream = null;
Bitmap output;
try { 
      int degree = PhotoUtil.readPictureDegree(path);                 
      fileInputStream = new FileInputStream(new File(path)); 
      output = BitmapFactory.decodeStream(fileInputStream); 
      showImage.setImageBitmap(
          PhotoUtil.rotaingImageView(degree,output));
    } catch (FileNotFoundException e) { 
      e.printStackTrace();
    }finally { 
      if (fileInputStream != null){
             try { fileInputStream.close(); 
                  } catch (IOException e) { 
                  e.printStackTrace(); 
                  } 
    }
}

其实拿到这个需要一下两句话就能拿到这个bitmap

fileInputStream = new FileInputStream(new File(path));
output = BitmapFactory.decodeStream(fileInputStream);

但是保存在本地的图片,直接这样取得的照片旋转了90度,其中图片的旋转角度是记录在exif中的,所以为了把图片旋转过来,索性直接利用exif去取角度

public static int readPictureDegree(String path) {    
      int degree  = 0;    
      try {        
            ExifInterface exifInterface = new ExifInterface(path);                          
            int orientation = exifInterface.getAttributeInt(    ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);       
         switch (orientation) {            
                case ExifInterface.ORIENTATION_ROTATE_90:                    
                        degree = 90;                
                        break;            
                case ExifInterface.ORIENTATION_ROTATE_180:                
                        degree = 180;                
                        break;            
                case ExifInterface.ORIENTATION_ROTATE_270:                
                        degree = 270;                
                        break;       
          }    
    } catch (IOException e) {        
            e.printStackTrace();    
    }   
    return degree;
}

然后根据取到的角度旋转bitmap

public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {
     Matrix matrix = new Matrix(); 
     matrix.postRotate(angle); 
     Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
     return resizedBitmap; 
}

对于图片的操作后面再说这样就能实现获得原图,并且能够正向的显示图片,但是很多app不只是拍一张照片而已,所以下面开始介绍自定义Camera

public class CameraView extends SurfaceView implements SurfaceHolder.Callback { 
    private Camera camera; 
    private SurfaceHolder holder; 
    private Context context; 
    private String picUrl; 

    public CameraView(Context context) { 
          super(context); 
          this.context = context; 
          initHolder(); 
    } 

    public CameraView(Context context, AttributeSet attrs) { 
          super(context, attrs); 
          this.context = context; 
          initHolder(); 
    } 

    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) { 
        super(context, attrs, defStyleAttr); 
        this.context = context; 
        initHolder(); 
    } 

   private void initHolder() { 
        holder = this.getHolder(); holder.addCallback(this);
   } 

    private boolean existCamera(Context context) { 
    return   context.getPackageManager().
        hasSystemFeature(PackageManager.FEATURE_CAMERA); 
    } 

    private void initCamera() {
         if (camera == null) { 
            camera = Camera.open(); 
         } 
    } 

    private void imagePreview(SurfaceHolder holder) { 
          try { 
                 if (camera != null) { 
                        camera.setPreviewDisplay(holder);   
                        camera.setDisplayOrientation(90); 
                        camera.startPreview(); 
                  }
             } catch (IOException e) {
                 e.printStackTrace(); 
             } 
 } 

    private void setParameters() { 
          if (camera != null) { 
                  Camera.Parameters parameters =          
                        camera.getParameters(); 
                  parameters.setPictureFormat(ImageFormat.JPEG);
                  parameters.setRotation(90);       
                  parameters.setFlashMode(
                          Camera.Parameters.FLASH_MODE_AUTO); 
                  camera.setParameters(parameters); 
          } 
    } 

    private void releaseCamera() { 
          if (camera != null) { 
               camera.setPreviewCallback(null); 
               camera.stopPreview();
               camera.release(); 
               camera = null; 
            } 
    } 

     public void autoFocus(){ 
          if (camera != null){ 
              camera.autoFocus(new Camera.AutoFocusCallback() { 

      @Override 
      public void onAutoFocus(boolean success, Camera camera) { 
            if (success){ 
                  takePicture();
            } 
      } 
    }); }
 } 

   public void takePicture(){    
        if (camera != null){        
            camera.takePicture(null, null, new Camera.PictureCallback() {           
           @Override           
           public void onPictureTaken(byte[] data, Camera camera) { 
               if (picUrl == null) {                    
                  picUrl = Environment.getExternalStorageDirectory() + File.separator + "zimo.jpg";               
               }               
             File file = new File(picUrl);               
             if (file.exists()) {                    
                  file.delete();                
            }               
            try {                    
              FileOutputStream fos = new FileOutputStream(file);                      
              fos.write(data);                    
              fos.close();                
            } catch (FileNotFoundException e) {                    
                  e.printStackTrace();                
            } catch (IOException e) {                    
                  e.printStackTrace();              
            }                
    
            imagePreview(holder);            
            }        
          });    
}}

@Override
public void surfaceCreated(SurfaceHolder holder) {    
        if (existCamera(context)){        
            initCamera();    
        }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    
        setParameters();    
        imagePreview(holder);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
            releaseCamera();
    }

public void setPicUrl(String picUrl) {    
          this.picUrl = picUrl;
}

上面是一个自定义的Camera,继承了SurfaceView 1. 检查Camera是否存在 2. 初始化Camera 3. 设置参数 4. 预览图片 5. 拍照 6. 释放Camera这就是自定义Camera实现的步骤了,当然还有增加权限

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

只要把CameraView当成自定义控件使用就好

<com.zimo.guo.customcamera.view.CameraView       
        android:id="@+id/camera" 
        android:layout_width="match_parent"     
        android:layout_height="match_parent" />

点击拍照按钮直接调用takePicture(),当然也可以自己定义图片地址

cameraView.setPicUrl(path);
cameraView.takePicture();

还可以实现聚焦之后自动拍照

cameraView.autoFocus();

下篇开始研究图片了,这篇就先到这!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容