要訪問設備攝像頭,你必須聲明 CAMERA你的Android清單的權限。此外,一定要包括 <用途特徵> 清單元素來聲明應用程序所使用的相機功能。例如,如果您使用的攝像頭和自動對焦功能,您應清單包括以下內容:
<uses-permission android:name="android.permission.CAMERA" />為了拍照這個類,使用下面的步驟:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
- 獲得從照相機的一個實例open(int)。
- 獲取與現有(默認)設置getParameters()。
- 如果有必要,修改返回的Camera.Parameters對象,然後調用 setParameters(Camera.Parameters)。
- 呼叫setDisplayOrientation(int)確保預覽的正確方向。
- 重要提示:通過完全初始化SurfaceHolder來 setPreviewDisplay(SurfaceHolder)。未經表面,相機將無法啟動預覽。
- 重要提示:呼叫startPreview()開始更新預覽表面。預覽必須先啟動,然後才能拍照。
- 當你想拍照 takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)來拍攝照片。等待回調提供實際的圖像數據。
- 拍攝照片後,預覽顯示將停止。要拍攝更多的照片,呼籲startPreview()。
- 呼叫stopPreview()停止更新預覽表面。
- 重要提示:呼叫release()其他應用程序來釋放相機的使用。應用程序應該立即釋放相機onPause()(並重新open() 它onResume())。
要快速切換到視頻拍攝模式,使用以下步驟:
- 獲得並初始化一個照相機和如上所述開始預覽。
- 打電話unlock()讓媒體進程訪問攝像頭。
- 通過相機setCamera(Camera)。請參閱MediaRecorder有關錄像的信息。
- 錄音完畢後,打電話reconnect()來重新獲取和重新鎖定相機。
- 如果需要的話,重新啟動預覽和採取更多照片或視頻。
- 呼叫stopPreview()和release()如上述。
code:
package com.example.cheng.camera_for_led;最後提醒的是,如果程序中加入了previewCallback,在surfaceDestroy釋放camera的時候,最好執行myCamera.setOneShotPreviewCallback(null); 或者myCamera.setPreviewCallback(null); 中止這種回調,然後再釋放camera更安全。否則可能會報錯。 Reference:
import android.app.Activity;
import android.content.Intent;
import android.hardware.Camera;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import static android.hardware.Camera.getNumberOfCameras;
public class MainActivity extends Activity implements SurfaceHolder.Callback {
private static final String TAG = "My_CAMERA";
Camera myCamera;
Button button1;
SurfaceView previewSurfaceView;
SurfaceHolder previewSurfaceHolder;
boolean previewing = false;
// 视频数据
private StreamIt streamIt = null;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFormat(PixelFormat.UNKNOWN);
previewSurfaceView = (SurfaceView) findViewById(R.id.previewsurface);
previewSurfaceHolder = previewSurfaceView.getHolder();// 绑定SurfaceView,取得SurfaceHolder对象
previewSurfaceHolder.addCallback(this);//SurfaceHolder加入回调接口
previewSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 設置顯示器類型,setType必须设置
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
myCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
});
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
Camera.Parameters parameters = myCamera.getParameters();//獲取Camera.Parameters的實例
myCamera.startPreview();
Log.d(TAG, format + "+" + width + "+" + height);
//Camera Focus mode 必須透過 setParameters() 設定,自動對焦則有三種模式
List<String> allFocus = parameters.getSupportedFocusModes();
if (allFocus.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);//设置聚焦模式
} else if (allFocus.contains(Camera.Parameters.FLASH_MODE_AUTO)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//设置聚焦模式
}
streamIt = new StreamIt();
myCamera.setDisplayOrientation(90);//螢幕轉向90度
myCamera.setPreviewCallback(streamIt);
myCamera.setParameters(parameters);// 设置Camera parameters
myCamera.startPreview();//開始捕獲並顯示幀
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (previewing) {//如果硬體沒有相機
myCamera.stopPreview();//停止相機功能
previewing = false;
}
myCamera = Camera.open();//開啟鏡頭(2.3版本后支持多摄像头,需传入参数)
int a = getNumberOfCameras();
Log.d(TAG + " number = ", String.valueOf(a));//硬體鏡頭可用數
try {///設置surface用來顯示實時的預覽
myCamera.setPreviewDisplay(holder);
Log.d(TAG, "start");
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
myCamera.stopPreview();//停止相机功能
myCamera.release();
myCamera = null;
previewing = false;
}
class StreamIt implements Camera.PreviewCallback {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.i(TAG, "执行了capture方法");
}
}
private void resetCam() {
myCamera.startPreview();
// parameters.setCamera(myCamera);
}
private void refreshGallery(File file) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(Uri.fromFile(file));
sendBroadcast(mediaScanIntent);
}
Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
new SaveImageTask().execute(data);
resetCam();
Log.d(TAG, "onPictureTaken - jpeg");
}
};
private class SaveImageTask extends AsyncTask<byte[], Void, Void> {
@Override
protected Void doInBackground(byte[]... data) {
FileOutputStream outStream = null;
// Write to SD Card
try {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/camtest");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
outStream = new FileOutputStream(outFile);
outStream.write(data[0]);
outStream.flush();
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());
refreshGallery(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "执行了onStart方法");
}
//Activity从后台重新回到前台时被调用
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "执行了onRestart方法");
}
//Activity创建或者从被覆盖、后台重新回到前台时被调用
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "执行了onResume方法");
}
//Activity被覆盖到下面或者锁屏时被调用
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "执行了onPause方法");
}
//退出当前Activity或者跳转到新Activity时被调用
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "执行了onStop方法");
}
//退出当前Activity时被调用,调用之后Activity就结束了
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "执行了onDestroy方法");
}
}
https://developer.android.com/reference/android/hardware/Camera.html#takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
https://developer.android.com/reference/android/hardware/Camera.html#getParameters()
https://developer.android.com/reference/android/hardware/Camera.html
https://github.com/josnidhin/Android-Camera-Example/blob/master/src/com/example/cam/CamTestActivity.java
http://fecbob.pixnet.net/blog/post/36606464-android-%E6%8B%8D%E7%85%A7api%E6%B5%81%E7%A8%8B
No comments:
Post a Comment