Android相機(jī)開(kāi)發(fā)
推薦幾個(gè)好的圖片選擇+拍照的框架
bilibili/boxing
LuckSiege/PictureSelector5900多個(gè)star
jeasonlzy/ImagePicker3600多個(gè)star
sucese/phoenix有Camera1和Camera2使用
只有相機(jī)功能
CameraKit/camerakit-android3900多個(gè)star
natario1/CameraView自由度很高的相機(jī)
申請(qǐng)權(quán)限
<uses-permission android:name="android.permission.CAMERA" />
<!--可以防止APP被安裝到?jīng)]有相機(jī)的Android設(shè)備上(目前僅Google Play支持)-->
<uses-feature android:name="android.hardware.camera" />
動(dòng)態(tài)權(quán)限不要忘了
創(chuàng)建一個(gè)可以預(yù)覽的界面
1.創(chuàng)建一個(gè)新工程
2.在新創(chuàng)建的工程中activity中布局文件
<FrameLayout
android:id="@+id/preview_f"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
3.創(chuàng)建一個(gè)相機(jī)預(yù)覽的view 繼承SurfaceView
最新都開(kāi)始用TextureView,關(guān)于SurfaceView/TextureView
- SurfaceView是一個(gè)有自己Surface的View中跌。界面渲染可以放在單獨(dú)線程而不是主線程中。它更像是一個(gè)Window菇篡,自身不能做變形和動(dòng)畫(huà)漩符。
- TextureView同樣也有自己的Surface。但是它只能在擁有硬件加速層層的Window中繪制驱还,它更像是一個(gè)普通View嗜暴,可以做變形和動(dòng)畫(huà)凸克。
更多關(guān)于SurfaceView與TextureView區(qū)別的內(nèi)容可以參考這篇文章Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView.
官方給出的方案闷沥,圖片來(lái)自于Android平臺(tái)Camera開(kāi)發(fā)實(shí)踐指南:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private final SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//surface第一次創(chuàng)建時(shí)回調(diào)
//打開(kāi)相機(jī)
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//surface變化的時(shí)候回調(diào)(格式/大小)
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//surface銷(xiāo)毀的時(shí)候回調(diào)
mHolder.removeCallback(this);
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
4.在activity中添加
public class MainActivity extends AppCompatActivity {
private FrameLayout mFrameLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initCamera();
}
private void initCamera() {
CameraPreview preview = new CameraPreview(this);
mFrameLayout.addView(preview);
}
private void initView() {
mFrameLayout = (FrameLayout) findViewById(R.id.preview_f);
}
}
至此可以顯示一個(gè)相機(jī)界面萎战,并有圖像顯示。
添加偏好設(shè)置
如分辨率舆逃、閃光燈蚂维、對(duì)焦等。
通過(guò)當(dāng)前界面的相機(jī)camera對(duì)象獲取起設(shè)置的參數(shù)getParameters()
預(yù)覽分辨率
-
parameters.getSupportedPreviewSizes()
獲取相機(jī)支持的所有預(yù)覽分辨率
預(yù)覽格式
具體參照ImageFormat或者自己Google
-
parameters.getSupportedPreviewFormats()
獲取相機(jī)支持的所有預(yù)覽格式
照片分辨率
-
parameters.getSupportedPictureSizes()
獲取相機(jī)支持的所有圖片分辨率
圖片格式
具體參照ImageFormat或者自己Google
-
parameters.getSupportedPictureFormats()
獲取相機(jī)支持的所有圖片格式
視頻分辨率
parameters.getSupportedVideoSizes()
獲取相機(jī)支持的所有視頻分辨率
對(duì)焦模式
-
parameters.getSupportedFocusModes()
獲取相機(jī)支持的所有對(duì)焦模式
曝光補(bǔ)償
-
parameters.getMinExposureCompensation()
獲取相機(jī)支持的最低曝光補(bǔ)償 -
parameters.getMaxExposureCompensation()
獲取相機(jī)支持的最高曝光補(bǔ)償
閃光燈模式
-
parameters.getSupportedFlashModes()
獲取相機(jī)支持的閃光燈模式
白平衡
-
parameters.getSupportedWhiteBalance()
獲取相機(jī)支持的白平衡
場(chǎng)景
parameters.getSupportedSceneModes()
獲取相機(jī)支持的場(chǎng)景
聲明GPS權(quán)限
想要拍到的照片中包含GPS信息
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
代碼如下
int numberOfCameras = Camera.getNumberOfCameras();
Log.d("123===", "相機(jī)個(gè)數(shù)===" + numberOfCameras);
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
//后置:0 CAMERA_FACING_BACK路狮; 前置:1 CAMERA_FACING_FRONT
Log.d("123===", "當(dāng)前相機(jī)信息=" + cameraInfo.facing);
}
Camera camera = mPreview.getCamera();
Camera.Parameters parameters = camera.getParameters();
Log.d("123===", "預(yù)覽分辨率-----------");
List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
for (Camera.Size previewSize : supportedPreviewSizes) {
Log.d("123===", previewSize.width + "---" + previewSize.height);
}
Log.d("123===", "預(yù)覽分辨率-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "獲得相機(jī)支持的圖片預(yù)覽格式-----------ImageFormat");
List<Integer> supportedPreviewFormats = parameters.getSupportedPreviewFormats();
for (Integer supportedPreviewFormat : supportedPreviewFormats) {
Log.d("123===", supportedPreviewFormat + "");
}
Log.d("123===", "獲得相機(jī)支持的圖片預(yù)覽格式-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "照片分辨率-----------");
List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
for (Camera.Size pictureSize : supportedPictureSizes) {
Log.d("123===", pictureSize.width + "---" + pictureSize.height);
}
Log.d("123===", "照片分辨率-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "獲得相機(jī)支持的圖片格式-----------ImageFormat");
List<Integer> supportedPictureFormats = parameters.getSupportedPictureFormats();
for (Integer supportedPreviewFormat : supportedPictureFormats) {
Log.d("123===", supportedPreviewFormat + "");
}
Log.d("123===", "獲得相機(jī)支持的圖片格式-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "視頻分辨率-----------");
List<Camera.Size> supportedVideoSizes = parameters.getSupportedVideoSizes();
for (Camera.Size supportedVideoSize : supportedVideoSizes) {
Log.d("123===", supportedVideoSize.width + "---" + supportedVideoSize.height);
}
Log.d("123===", "視頻分辨率-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "對(duì)焦模式-----------ImageFormat");
List<String> supportedFocusModes = parameters.getSupportedFocusModes();
for (String supportedFocusMode : supportedFocusModes) {
Log.d("123===", supportedFocusMode + "");
}
Log.d("123===", "對(duì)焦模式-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "曝光補(bǔ)償-----------");
int minExposureCompensation = parameters.getMinExposureCompensation();
int maxExposureCompensation = parameters.getMaxExposureCompensation();
Log.d("123===", "最高=" + maxExposureCompensation);
Log.d("123===", "最低=" + minExposureCompensation);
Log.d("123===", "曝光補(bǔ)償-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "支持閃光燈模式-----------");
List<String> supportedFlashModes = parameters.getSupportedFlashModes();
for (String supportedFlashMode : supportedFlashModes) {
Log.d("123===", "閃光模式--->" + supportedFlashMode);
}
Log.d("123===", "支持閃光燈模式-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "支持白平衡-----------");
List<String> supportedWhiteBalance = parameters.getSupportedWhiteBalance();
for (String s : supportedWhiteBalance) {
Log.d("123===", "--->" + s);
}
Log.d("123===", "支持白平衡-----------");
Log.d("123===", "");
Log.d("123===", "");
Log.d("123===", "場(chǎng)景-----------");
List<String> supportedSceneModes = parameters.getSupportedSceneModes();
for (String s : supportedSceneModes) {
Log.d("123===", "--->" + s);
}
Log.d("123===", "場(chǎng)景-----------");
Log.d("123===", "");
Log.d("123===", "");
拍照虫啥,視頻,對(duì)焦
假如需要使用原生拍照功能的話,Camera#takePicture()
拍照和視頻都是網(wǎng)上那一套流程奄妨,具體的因?yàn)闀r(shí)間原因暫時(shí)先這樣了涂籽。
相機(jī)預(yù)覽和保存注意事項(xiàng)
下面三張圖片引用自:Android: Camera相機(jī)開(kāi)發(fā)詳解(中) ——實(shí)現(xiàn)預(yù)覽、拍照砸抛、保存照片等功能
- 相機(jī)預(yù)覽方向
- 采集的圖像方向
- 前置攝像頭預(yù)覽與保存一致
參考
- Android相機(jī)開(kāi)發(fā)系列
- Android Camera相機(jī)開(kāi)發(fā)詳解
- Android: Camera相機(jī)開(kāi)發(fā)詳解(上) —— 知識(shí)儲(chǔ)備
- Android: Camera相機(jī)開(kāi)發(fā)詳解(中) ——實(shí)現(xiàn)預(yù)覽评雌、拍照、保存照片等功能
- Android 相機(jī)(二): 最詳細(xì)的自定義相機(jī)的步驟拆解
- Android平臺(tái)Camera開(kāi)發(fā)實(shí)踐指南 這有Camera2的知識(shí)
- Android設(shè)備對(duì)新Camera2 API的支持問(wèn)題:以華為M2為例