camerax 自动聚焦_Android Camera-CameraView和CameraX使用
前面兩篇介紹了Camera1和Camera2的使用,發(fā)現(xiàn)Camera API從1到2的變化非常大,Camera2的復(fù)雜度提升了不少,官方為了讓我們更容易使用Camera,出了個(gè)一個(gè)官方的庫(kù)cameraview。不過這個(gè)庫(kù)已經(jīng)Deprecated,官方建議使用Jetpack CameraX 替代。本篇文章就介紹下CameraView和CameraX的使用
CameraView
CameraView的目的就是幫助開發(fā)者能夠快速集成Camera1和Camera2的特性,可以用下面這張表來說明:
API Level
Camera API
Preview View
9-13
Camera1
SurfaceView
14-20
Camera1
TextureView
21-23
Camera2
TextureView
24
Camera2
SurfaceView
開發(fā)流程
CameraView定義
xml中定義
android:id="@+id/camera"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keepScreenOn="true"
android:adjustViewBounds="true"
app:autoFocus="true"
app:aspectRatio="4:3"
app:facing="back"
app:flash="auto"/>
xml中可以配置:
autoFocus:是否自動(dòng)對(duì)焦
aspectRatio:預(yù)覽畫面比例
facing:前后攝像頭
flash:閃光燈模式
增加生命周期
@Override
protected void onResume() {
super.onResume();
mCameraView.start();
}
@Override
protected void onPause() {
mCameraView.stop();
super.onPause();
}
這樣聲明后,就可以完成預(yù)覽的工作了
相機(jī)狀態(tài)回調(diào)
在xml聲明CameraView后,增加回調(diào)
if (mCameraView != null) {
mCameraView.addCallback(mCallback);
}
...
private CameraView.Callback mCallback
= new CameraView.Callback() {
@Override
public void onCameraOpened(CameraView cameraView) {
Log.d(TAG, "onCameraOpened");
}
@Override
public void onCameraClosed(CameraView cameraView) {
Log.d(TAG, "onCameraClosed");
}
@Override
public void onPictureTaken(CameraView cameraView, final byte[] data) {
Log.d(TAG, "onPictureTaken " + data.length);
Toast.makeText(cameraView.getContext(), R.string.picture_taken, Toast.LENGTH_SHORT)
.show();
getBackgroundHandler().post(new Runnable() {
@Override
public void run() {
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),
"picture.jpg");
Log.d(TAG, "onPictureTaken file path: " + file.getPath());
OutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(data);
os.close();
} catch (IOException e) {
Log.w(TAG, "Cannot write to " + file, e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
}
}
}
});
}
};
有三個(gè)回調(diào)方法,相機(jī)打開,相機(jī)關(guān)閉,和拍照。
拍照
mCameraView.takePicture();
就是這么簡(jiǎn)單,點(diǎn)擊后拍照,然后回調(diào)中處理圖像數(shù)據(jù)
CameraX
CameraX 是一個(gè) Jetpack 支持庫(kù),目的是簡(jiǎn)化Camera的開發(fā)工作,它是基于Camera2 API的基礎(chǔ),向后兼容至 Android 5.0(API 級(jí)別 21)。
它有以下幾個(gè)特性:
易用性,只需要幾行代碼就可以實(shí)現(xiàn)預(yù)覽和拍照
保持設(shè)備的一致性,在不同相機(jī)設(shè)備上,對(duì)寬高比、屏幕方向、旋轉(zhuǎn)、預(yù)覽大小和高分辨率圖片大小,做到都可以正常使用
相機(jī)特性的擴(kuò)展,增加人像、HDR、夜間模式和美顏等功能
開發(fā)流程
庫(kù)引用
目前CameraX最新版本是1.0.0-alpha06,在app的build.gradle引用:
dependencies {
// CameraX core library.
def camerax_version = "1.0.0-alpha06"
implementation "androidx.camera:camera-core:${camerax_version}"
// If you want to use Camera2 extensions.
implementation "androidx.camera:camera-camera2:${camerax_version}"
def camerax_view_version = "1.0.0-alpha03"
def camerax_ext_version = "1.0.0-alpha03"
//other
// If you to use the Camera View class
implementation "androidx.camera:camera-view:$camerax_view_version"
// If you to use Camera Extensions
implementation "androidx.camera:camera-extensions:$camerax_ext_version"
}
因?yàn)镃ameraX是一個(gè) Jetpack 支持庫(kù),相機(jī)的打開和釋放都是使用了Jetpack的Lifecycle來進(jìn)行處理。
預(yù)覽
預(yù)覽參數(shù)設(shè)置,使用PreviewConfig.Builder()實(shí)現(xiàn):
PreviewConfig config = new PreviewConfig.Builder()
.setLensFacing(CameraX.LensFacing.BACK)
.setTargetRotation(mTextureView.getDisplay().getRotation())
.setTargetResolution(new Size(640, 480))
.build();
Preview preview = new Preview(config);
preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {
@Override
public void onUpdated(@NonNull Preview.PreviewOutput output) {
if (mTextureView.getParent() instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) mTextureView.getParent();
viewGroup.removeView(mTextureView);
viewGroup.addView(mTextureView, 0);
mTextureView.setSurfaceTexture(output.getSurfaceTexture());
updateTransform();
}
}
});
//lifecycle
CameraX.bindToLifecycle(this, preview);
PreivewConfig.Builder可以設(shè)置的屬性很多,這里只設(shè)置了攝像頭、旋轉(zhuǎn)方向、預(yù)覽分辨率,還有很多其他方法,大家可以自行試驗(yàn)。
在preview回調(diào)監(jiān)聽中,把output的SurfaceTexture設(shè)置到mTextureView中,實(shí)現(xiàn)圖像預(yù)覽,最后增加Lifecycle的綁定。
拍照
ImageCaptureConfig captureConfig = new ImageCaptureConfig.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_16_9)
.setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
.setTargetRotation(getWindowManager().getDefaultDisplay().getRotation())
.build();
ImageCapture imageCapture = new ImageCapture(captureConfig);
mTakePicture.setOnClickListener((view) -> {
final File file = new File(getExternalMediaDirs()[0], System.currentTimeMillis() + ".jpg");
Log.d("DEBUG", "##### file path: " + file.getPath());
imageCapture.takePicture(file, ContextCompat.getMainExecutor(getApplicationContext()), new ImageCapture.OnImageSavedListener() {
@Override
public void onImageSaved(@NonNull File file) {
Log.d("DEBUG", "##### onImageSaved: " + file.getPath());
}
@Override
public void onError(@NonNull ImageCapture.ImageCaptureError imageCaptureError, @NonNull String message, @Nullable Throwable cause) {
Log.d("DEBUG", "##### onError: " + message);
}
});
});
CameraX.bindToLifecycle(this, preview, imageCapture);
拍照的參數(shù)通過ImageCaptureConfig.Builder設(shè)置,這里只設(shè)置了圖片寬高比、拍攝模式和旋轉(zhuǎn)方向,還有很多其他方法,大家可以自行試驗(yàn)。
真正調(diào)用拍照的方法:
takePicture(OnImageCapturedListener):此方法為拍攝的圖片提供內(nèi)存緩沖區(qū)。
takePicture(File, OnImageSavedListener):此方法將拍攝的圖片保存到提供的文件位置。
takePicture(File, OnImageSavedListener, Metadata):此方法可用于指定要嵌入已保存文件的 Exif 中的元數(shù)據(jù)。
例子調(diào)用的是takePicture(File, OnImageSavedListener),直接存為文件。最后再增加Lifecycle的綁定。
圖片分析
ImageAnalysisConfig analysisConfig = new ImageAnalysisConfig.Builder()
.setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
.build();
ImageAnalysis imageAnalysis = new ImageAnalysis(analysisConfig);
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(getApplicationContext()),
new LuminosityAnalyzer());
CameraX.bindToLifecycle(this, preview, imageCapture, imageAnalysis);
...
private class LuminosityAnalyzer implements ImageAnalysis.Analyzer {
private long lastAnalyzedTimestamp = 0L;
@Override
public void analyze(ImageProxy image, int rotationDegrees) {
final Image img = image.getImage();
if (img != null) {
Log.d("DEBUG", img.getWidth() + "," + img.getHeight());
}
}
}
圖片分析,不是必要的步驟,但是ImageAnalysis,可以對(duì)每幀圖像進(jìn)行分析。
設(shè)置參數(shù)通過ImageAnalysisConfig.Builder(),這里只設(shè)置了ImageReaderMode,它有兩種模式:
阻止模式(ImageReaderMode.ACQUIRE_NEXT_IMAGE):就是Camera2中的acquireNextImage(),獲取下一個(gè)最新的可用Image
非阻止模式(ImageReaderMode.ACQUIRE_LATEST_IMAGE):Camera2中的acquireLatestImage(),獲得圖像隊(duì)列中最新的圖片,并且會(huì)清空隊(duì)列,刪除已有的舊的圖像
最后還是增加Lifecycle的綁定。CameraX的使用也非常簡(jiǎn)單,把Camera2中復(fù)雜的API封裝到統(tǒng)一的config中,只需要幾行代碼,就實(shí)現(xiàn)需要的功能。
文章中涉及到的代碼
參考
總結(jié)
以上是生活随笔為你收集整理的camerax 自动聚焦_Android Camera-CameraView和CameraX使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leslie人口预测模型matlab代码
- 下一篇: android 文件选择器_Androi