Android實現(xiàn)攝像頭拍照功能
應用場景:
在Android開發(fā)過程中,有時需要調(diào)用手機自身設備的功能,本文側(cè)重攝像頭拍照功能的調(diào)用。
知識點介紹:
使用權限:調(diào)用手機自身設備功能(攝像頭拍照功能),應該確保已經(jīng)在AndroidManifest.xml中正確聲明了對攝像頭的使用及其它相關的feature。
<!--攝像頭權限 --> <uses-permission android:name="android.permission.CAMERA" /> <!--存儲權限 SD卡讀寫權限 --> <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" /> <!--視頻、錄音權限 請求音頻捕獲權限 --> <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;
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android實現(xiàn)EditText中添加和刪除bitmap的方法
這篇文章主要介紹了Android實現(xiàn)EditText中添加和刪除bitmap的方法,實例分析了Android中EditText控件的bitmap操作技巧,需要的朋友可以參考下2016-01-01
漂亮的Android音樂歌詞控件 仿網(wǎng)易云音樂滑動效果
這篇文章主要為大家詳細介紹了漂亮的Android音樂歌詞控件,仿網(wǎng)易云音樂滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01
Android開發(fā)之在程序中時時獲取logcat日志信息的方法(附demo源碼下載)
這篇文章主要介紹了Android開發(fā)之在程序中時時獲取logcat日志信息的方法,結(jié)合實例形式較為詳細的分析了實時獲取logcat日志的原理、步驟與相關實現(xiàn)技巧,并附帶相應的demo源碼供讀者下載參考,需要的朋友可以參考下2016-02-02
Android?Jetpack結(jié)構運用Compose實現(xiàn)微博長按點贊彩虹效果
Compose在動畫方面下足了功夫,提供了豐富的API。但也正由于API種類繁多,如果想一氣兒學下來,最終可能會消化不良,導致似懂非懂。結(jié)合例子學習是一個不錯的方法,本文就帶大家邊學邊做,通過實現(xiàn)一個微博長按點贊的動畫效果,學習了解Compose動畫的常見思路和開發(fā)技巧2022-07-07
android 實現(xiàn)APP中改變頭像圖片的實例代碼
這篇文章主要介紹了android 實現(xiàn)APP中改變頭像圖片的實例代碼,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07

