溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android實現(xiàn)攝像頭拍照功能

發(fā)布時間:2020-10-16 05:03:37 來源:腳本之家 閱讀:146 作者:Hoking 欄目:移動開發(fā)

應用場景:

在Android開發(fā)過程中,有時需要調(diào)用手機自身設備的功能,本文側(cè)重攝像頭拍照功能的調(diào)用。

知識點介紹:

使用權(quán)限:調(diào)用手機自身設備功能(攝像頭拍照功能),應該確保已經(jīng)在AndroidManifest.xml中正確聲明了對攝像頭的使用及其它相關(guān)的feature。

<!--攝像頭權(quán)限 --> 
 <uses-permission android:name="android.permission.CAMERA" /> 
 <!--存儲權(quán)限  SD卡讀寫權(quán)限 --> 
 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> 
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
 <!--Camera Feature 聲明對camera feature的使用 --> 
 <uses-feature android:name="android.hardware.camera" /> 
 <uses-feature 
 android:name="android.hardware.camera.autofocus" 
 android:required="false" /> 
 <!--視頻、錄音權(quán)限  請求音頻捕獲權(quán)限 --> 
 <uses-permission android:name="android.permission.RECORD_VIDEO"/> 
<uses-permission android:name="android.permission.RECORD_AUDIO"/> 

Class類:

1、 SurfaceView
視圖(View)的繼承類,這個視圖里內(nèi)嵌了一個專門用于繪制的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪制位置。
2、 SurfaceHolder
SurfaceHolder是控制surface的一個抽象接口,你可以通過SurfaceHolder來控制surface的尺寸和格式,或者修改surface的像素,監(jiān)視surface的變化等等,SurfaceHolder是SurfaceView的典型接口。
3、 SurfaceHolder.Callback
用戶可以實現(xiàn)此接口接收surface變化的消息。當用在一個SurfaceView 中時,  它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之間有效。設置Callback的方法是SurfaceHolder.addCallback。

使用方式:

第一步:新建一個Android項目CameraTest,包含兩個Activity: MainActivity、CameraActivity。

第二步:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:layout_width="match_parent" 
 android:background="#FFFFFF" 
 android:layout_height="match_parent" 
 tools:context=".MainActivity" > 
 <LinearLayout android:layout_height="wrap_content" 
 android:layout_width="match_parent"> 
 <ImageView 
 android:id="@+id/main_image" 
 android:layout_height="wrap_content" 
 android:src="@drawable/ic_launcher" 
 android:layout_width="match_parent"/> 
 </LinearLayout> 
 <LinearLayout 
 android:layout_height="wrap_content" 
 android:layout_width="match_parent" 
 android:layout_alignParentBottom="true" 
 android:layout_marginBottom="20dp" 
 android:orientation="horizontal"> 
 <Button android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:layout_weight="1" 
 android:id="@+id/main_camera" 
 android:text="拍照"/> 
 <Button android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:layout_weight="1" 
 android:text="退出" 
 android:id="@+id/main_quit"/> 
 </LinearLayout> 
</RelativeLayout> 

MainActivity.java

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
 
import android.os.Bundle; 
import android.app.Activity; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.util.Log; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.ImageView; 
 
public class MainActivity extends Activity { 
 
 private Button cameraButton; //拍照按鈕 
 private Button quitButton; //退出按鈕 
 private ImageView imageView; //圖片顯示 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 setContentView(R.layout.activity_main); 
 initViews(); 
 } 
 
 private void initViews() { 
 imageView = (ImageView) findViewById(R.id.main_image); 
// 從本地取圖片(在sdcard中獲取文件) 
 Bitmap bitmap = getLoacalBitmap("/sdcard/mhc.jpg"); 
 Log.e("msgTag", new File("/sdcard/mhc.jpg").exists()+"=========="); 
 imageView .setImageBitmap(bitmap); //設置Bitmap 
 cameraButton = (Button) findViewById(R.id.main_camera); 
 quitButton = (Button) findViewById(R.id.main_quit); 
 MainOnClickListener mainOnClickListener = new MainOnClickListener(); 
 cameraButton.setOnClickListener(mainOnClickListener); 
 quitButton.setOnClickListener(mainOnClickListener); 
 } 
 
 private class MainOnClickListener implements OnClickListener{ 
 
 @Override 
 public void onClick(View v) { 
 switch (v.getId()) { 
 case R.id.main_camera: 
 startActivity(new Intent(MainActivity.this, CameraActivity.class)); 
 break; 
 case R.id.main_quit: 
 MainActivity.this.finish(); 
 break; 
 default: 
 break; 
 } 
 } 
 } 
 
 /** 
 * 根據(jù)文件路徑獲取所需要文件,并將該文件封裝成Bitmap對象返回 
 * @param fileUrl 
 * @return 
 */ 
 public static Bitmap getLoacalBitmap(String fileUrl) { 
 try { 
 FileInputStream fis = new FileInputStream(fileUrl); 
 return BitmapFactory.decodeStream(fis); ///把流轉(zhuǎn)化為Bitmap圖片 
 } catch (FileNotFoundException e) { 
 e.printStackTrace(); 
 return null; 
 } 
 } 
} 

activity_camera.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:background="#FFFFFF" 
 tools:context=".CameraActivity" > 
 
 <LinearLayout 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" > 
 <SurfaceView 
 android:id="@+id/camera_preview" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:layout_gravity="center_vertical|center_horizontal" /> 
 </LinearLayout> 
 <LinearLayout 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:layout_alignParentBottom="true"> 
 <Button 
 android:id="@+id/camera_save" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:text="拍照" /> 
 </LinearLayout> 
</RelativeLayout> 

CameraActivity.java

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
 
import android.graphics.ImageFormat; 
import android.hardware.Camera; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.app.Activity; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
 
public class CameraActivity extends Activity { 
 private String tag ="CameraActivity"; 
 private SurfaceView surfaceView; 
 //Surface的控制器 
 private SurfaceHolder surfaceHolder; 
 private Camera camera; 
 private Button saveButton; 
 //拍照的回調(diào)接口 
 private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() { 
 public void onPictureTaken(byte[] data, Camera camera) { 
 new SavePictureTask().execute(data); 
 camera.startPreview(); 
 } 
 }; 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 setContentView(R.layout.activity_camera); 
 initViews(); 
 } 
 
 private void initViews() { 
 saveButton = (Button) findViewById(R.id.camera_save); 
 surfaceView = (SurfaceView) findViewById(R.id.camera_preview); 
 surfaceHolder = surfaceView.getHolder(); 
 // 給SurfaceView當前的持有者 SurfaceHolder 一個回調(diào)對象。 
 //用戶可以實現(xiàn)此接口接收surface變化的消息。當用在一個SurfaceView 中時, 
 //它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之間有效。 
 //設置Callback的方法是SurfaceHolder.addCallback. 
 //實現(xiàn)過程一般繼承SurfaceView并實現(xiàn)SurfaceHolder.Callback接口 
 surfaceHolder.addCallback(surfaceCallback); 
 // 設置surface不需要自己的維護緩存區(qū) 
 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
 saveButton.setOnClickListener(new OnClickListener() { 
 
 @Override 
 public void onClick(View v) { 
 camera.takePicture(null, null, pictureCallback); 
// Camera.takePicture(shutterCallback,rawCallback,pictureCallback ); 
// private ShutterCallback shutterCallback = new ShutterCallback(){ 
//  public void onShutter(){ 
//  /* 按快門瞬間會執(zhí)行這里的代碼 */ 
//  } 
//  }; 
// private PictureCallback rawCallback = new PictureCallback(){ 
//  public void onPictureTaken(byte[] _data, Camera _camera){ 
//  /* 如需要處理 raw 則在這里 寫代碼 */ 
//  } 
//  }; 
//  //當拍照后 存儲JPG文件到 sd卡 
//  PictureCallback pictureCallback=new PictureCallback(){ 
//  public void onPictureTaken(byte[] data,Camera camera) { 
//  FileOutputStream outSteam=null; 
//  try{ 
//  SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss"); 
//  String times=format.format((new Date())); 
//  outSteam=new FileOutputStream("/sdcard/"+times+"mhc.jpg"); 
//  outSteam.write(data); 
//  outSteam.close(); 
//  }catch(FileNotFoundException e){ 
//  Log.d("Camera", "row"); 
//  } catch (IOException e) { 
//  e.printStackTrace(); 
//  } 
//  }; 
//  }; 
 } 
 }); 
 } 
 
 
 //SurfaceView當前的持有者的回調(diào)接口的實現(xiàn) 
 SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { 
 
 @Override 
 public void surfaceCreated(SurfaceHolder holder) { 
 camera = Camera.open(); 
 Log.e(tag, "攝像頭Open完成"); 
 try { 
 camera.setPreviewDisplay(holder); 
 } catch (IOException e) { 
 camera.release(); 
 camera = null; 
 } 
 } 
 
 @Override 
 public void surfaceChanged(SurfaceHolder holder, int format, int width, 
 int height) { 
 Camera.Parameters parameters = camera.getParameters(); 
 parameters.setPictureFormat(ImageFormat.JPEG); 
 camera.setDisplayOrientation(0); 
 camera.setParameters(parameters); 
 camera.startPreview(); 
 } 
 
 @Override 
 public void surfaceDestroyed(SurfaceHolder holder) { 
 camera.stopPreview(); 
 camera.release(); 
 camera = null; 
 } 
 }; 
 
 class SavePictureTask extends AsyncTask<byte[], String, String> { 
 @Override 
 protected String doInBackground(byte[]... params) { 
 File picture = new File("/sdcard/mhc.jpg"); 
 try { 
 FileOutputStream fos = new FileOutputStream(picture.getPath()); 
 fos.write(params[0]); 
 fos.close(); 
 } catch (Exception e) { 
 e.printStackTrace(); 
 } 
 Log.e(tag, "照片保存完成"); 
 CameraActivity.this.finish(); 
 return null; 
 } 
 } 
} 

下載地址:Android實現(xiàn)攝像頭拍照功能

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI