android 之 camera

由于我剛?cè)肼毈F(xiàn)在的這家公司的時(shí)候,他們對(duì)涉及到圖片的比較多,所以打算寫一系列圖片的文章,首先就從制造圖片的地方開始寫起--Camera如果你的app里面只是需要拍一張照片,只需要調(diào)用系統(tǒng)的照相機(jī)就可以滿足你的需求了通過ACTION_IMAGE_CAPTURE調(diào)用系統(tǒng)的照相機(jī)

intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);

然后在通過startActivityForResult方法跳轉(zhuǎn)onActivityResult:

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

一般的情況下這樣就滿足了你的需求,也不需要增加權(quán)限,但是這里需要注意的是通過data獲得的是一張縮略圖,如果想獲得一張?jiān)瓐D,就需要指定圖片的保存地址

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

同樣使用startActivityForResult方法跳轉(zhuǎn)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(); 
                  } 
    }
}

其實(shí)拿到這個(gè)需要一下兩句話就能拿到這個(gè)bitmap

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

但是保存在本地的圖片,直接這樣取得的照片旋轉(zhuǎn)了90度,其中圖片的旋轉(zhuǎn)角度是記錄在exif中的,所以為了把圖片旋轉(zhuǎn)過來,索性直接利用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;
}

然后根據(jù)取到的角度旋轉(zhuǎn)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; 
}

對(duì)于圖片的操作后面再說這樣就能實(shí)現(xiàn)獲得原圖,并且能夠正向的顯示圖片,但是很多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;
}

上面是一個(gè)自定義的Camera,繼承了SurfaceView 1. 檢查Camera是否存在 2. 初始化Camera 3. 設(shè)置參數(shù) 4. 預(yù)覽圖片 5. 拍照 6. 釋放Camera這就是自定義Camera實(shí)現(xiàn)的步驟了,當(dāng)然還有增加權(quán)限

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

只要把CameraView當(dāng)成自定義控件使用就好

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

點(diǎn)擊拍照按鈕直接調(diào)用takePicture(),當(dāng)然也可以自己定義圖片地址

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

還可以實(shí)現(xiàn)聚焦之后自動(dòng)拍照

cameraView.autoFocus();

下篇開始研究圖片了,這篇就先到這!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,932評(píng)論 25 709
  • 在APP中使用camera的兩種方式 調(diào)用系統(tǒng)相機(jī),或具有相機(jī)功能的應(yīng)用。 /** * 啟動(dòng)相機(jī)...
    蒹葭流閱讀 723評(píng)論 0 2
  • 如以上DEMO截圖所示效果,我們對(duì)于這種類似的功能肯定不算陌生,因?yàn)檫@可以說是實(shí)際開發(fā)中一類非常常見的功能需求了。...
    Machivellia閱讀 2,626評(píng)論 1 13
  • Android中開發(fā)相機(jī)的兩種方式Android系統(tǒng)提供了兩種使用手機(jī)相機(jī)資源實(shí)現(xiàn)拍攝功能的方法,一種是直接通過I...
    開發(fā)者也閱讀 3,120評(píng)論 0 14
  • 幼時(shí)庭院小棗熟,風(fēng)吹果香引蝶舞。 閃亮紅珠枝頭笑,樹下孩童涎水流。 繞樹千回尋覓爬,可伶身小急撓頭。 老翁笑指北墻...
    北歸燕閱讀 269評(píng)論 0 5

友情鏈接更多精彩內(nèi)容