HarmonyOS相機(jī)模塊支持相機(jī)業(yè)務(wù)的開發(fā),開發(fā)者可以通過已開放的接口實(shí)現(xiàn)相機(jī)硬件的訪問、操作和新功能開發(fā),最常見的操作如:預(yù)覽、拍照、連拍和錄像等。
基本概念
-
相機(jī)靜態(tài)能力
用于描述相機(jī)的固有能力的一系列參數(shù),比如朝向、支持的分辨率等信息。
-
物理相機(jī)
物理相機(jī)就是獨(dú)立的實(shí)體攝像頭設(shè)備。物理相機(jī)ID是用于標(biāo)志每個(gè)物理攝像頭的唯一字串。
-
邏輯相機(jī)
邏輯相機(jī)是多個(gè)物理相機(jī)組合出來的抽象設(shè)備,邏輯相機(jī)通過同時(shí)控制多個(gè)物理相機(jī)設(shè)備來完成相機(jī)某些功能,如大光圈、變焦等功能。邏輯攝像機(jī)ID是一個(gè)唯一的字符串,標(biāo)識(shí)多個(gè)物理攝像機(jī)的抽象能力。
-
幀捕獲
相機(jī)啟動(dòng)后對(duì)幀的捕獲動(dòng)作統(tǒng)稱為幀捕獲。主要包含單幀捕獲、多幀捕獲、循環(huán)幀捕獲。
-
單幀捕獲
指的是相機(jī)啟動(dòng)后,在幀數(shù)據(jù)流中捕獲一幀數(shù)據(jù),常用于普通拍照。
-
多幀捕獲
指的是相機(jī)啟動(dòng)后,在幀數(shù)據(jù)流中連續(xù)捕獲多幀數(shù)據(jù),常用于連拍。
-
循環(huán)幀捕獲
指的是相機(jī)啟動(dòng)后,在幀數(shù)據(jù)流中一直捕獲幀數(shù)據(jù),常用于預(yù)覽和錄像。
約束與限制
- 在同一時(shí)刻只能有一個(gè)相機(jī)應(yīng)用在運(yùn)行中。
- 相機(jī)模塊內(nèi)部有狀態(tài)控制,開發(fā)者必須按照指導(dǎo)文檔中的流程進(jìn)行接口的順序調(diào)用,否則可能會(huì)出現(xiàn)調(diào)用失敗等問題。
- 為了開發(fā)的相機(jī)應(yīng)用擁有更好的兼容性,在創(chuàng)建相機(jī)對(duì)象或者參數(shù)相關(guān)設(shè)置前請(qǐng)務(wù)必進(jìn)行能力查詢。
相機(jī)開發(fā)流程
相機(jī)模塊主要工作是給相機(jī)應(yīng)用開發(fā)者提供基本的相機(jī)API接口,用于使用相機(jī)系統(tǒng)的功能,進(jìn)行相機(jī)硬件的訪問、操作和新功能開發(fā)。相機(jī)的開發(fā)流程如圖所示:
接口說明
相機(jī)模塊為相機(jī)應(yīng)用開發(fā)者提供了3個(gè)包的內(nèi)容,包括方法、枚舉、以及常量/變量,方便開發(fā)者更容易地實(shí)現(xiàn)相機(jī)功能。詳情請(qǐng)查閱對(duì)應(yīng)開發(fā)場(chǎng)景。
包名 |
功能 |
---|---|
ohos.media.camera.CameraKit |
相機(jī)功能入口類。獲取當(dāng)前支持的相機(jī)列表及其靜態(tài)能力信息,創(chuàng)建相機(jī)對(duì)象。 |
ohos.media.camera.device |
相機(jī)設(shè)備操作類。提供相機(jī)能力查詢、相機(jī)配置、相機(jī)幀捕獲、相機(jī)狀態(tài)回調(diào)等功能。 |
ohos.media.camera.params |
相機(jī)參數(shù)類。提供相機(jī)屬性、參數(shù)和操作結(jié)果的定義。 |
相機(jī)權(quán)限申請(qǐng)
在使用相機(jī)之前,需要申請(qǐng)相機(jī)的相關(guān)權(quán)限,保證應(yīng)用擁有相機(jī)硬件及其他功能權(quán)限,相機(jī)涉及權(quán)限如下表。
權(quán)限名稱 |
權(quán)限屬性值 |
是否必選 |
---|---|---|
相機(jī)權(quán)限 |
ohos.permission.CAMERA |
必選 |
錄音權(quán)限 |
ohos.permission.MICROPHONE |
可選(需要錄像時(shí)申請(qǐng)) |
存儲(chǔ)權(quán)限 |
ohos.permission.WRITE_MEDIA |
可選(需要保存圖像及視頻到設(shè)備的外部存儲(chǔ)時(shí)申請(qǐng)) |
位置權(quán)限 |
ohos.permission.MEDIA_LOCATION |
可選(需要保存圖像及視頻位置信息時(shí)申請(qǐng)) |
相機(jī)設(shè)備創(chuàng)建
CameraKit類是相機(jī)的入口API類,用于獲取相機(jī)設(shè)備特性、打開相機(jī),其接口如下表。
接口名 |
描述 |
---|---|
createCamera?(String cameraId, CameraStateCallback callback, EventHandler handler) |
創(chuàng)建相機(jī)對(duì)象。 |
getCameraAbility?(String cameraId) |
獲取指定邏輯相機(jī)或物理相機(jī)的靜態(tài)能力。 |
getCameraIds?() |
獲取當(dāng)前邏輯相機(jī)列表。 |
getCameraInfo?(String cameraId) |
獲取指定邏輯相機(jī)的信息。 |
getInstance?(Context context) |
獲取CameraKit實(shí)例。 |
registerCameraDeviceCallback?(CameraDeviceCallback callback, EventHandler handler) |
注冊(cè)相機(jī)使用狀態(tài)回調(diào)。 |
unregisterCameraDeviceCallback?(CameraDeviceCallback callback) |
注銷相機(jī)使用狀態(tài)回調(diào)。 |
在實(shí)現(xiàn)一個(gè)相機(jī)應(yīng)用之前必須先創(chuàng)建一個(gè)獨(dú)立的相機(jī)設(shè)備,然后才能繼續(xù)相機(jī)的其他操作。相機(jī)設(shè)備創(chuàng)建的建議步驟如下:
1. 通過CameraKit.getInstance(Context context)方法獲取唯一的CameraKit對(duì)象
private void openCamera(){
// 獲取CameraKit對(duì)象
CameraKit cameraKit = CameraKit.getInstance(getApplicationContext());
if (cameraKit == null) {
// 處理cameraKit獲取失敗的情況
}
}
如果此步驟操作失敗,相機(jī)可能被占用或無法使用。如果被占用,必須等到相機(jī)釋放后才能重新獲取CameraKit對(duì)象。
2. 通過getCameraIds()方法,獲取當(dāng)前使用的設(shè)備支持的邏輯相機(jī)列表。邏輯相機(jī)列表中存儲(chǔ)了當(dāng)前設(shè)備擁有的所有邏輯相機(jī)ID,如果列表不為空,則列表中的每個(gè)ID都支持獨(dú)立創(chuàng)建相機(jī)對(duì)象;否則,說明正在使用的設(shè)備無可用的相機(jī),不能繼續(xù)后續(xù)的操作。
try {
// 獲取當(dāng)前設(shè)備的邏輯相機(jī)列表
String[] cameraIds = cameraKit.getCameraIds();
if (cameraIds.length <= 0) {
HiLog.error(LABEL, "cameraIds size is 0");
}
} catch (IllegalStateException e) {
// 處理異常
}
還可以繼續(xù)查詢指定相機(jī)ID的靜態(tài)信息:
調(diào)用getDeviceLinkType?(String physicalId)方法獲取物理相機(jī)連接方式;
調(diào)用getCameraInfo(String cameraId)方法查詢相機(jī)硬件朝向等信息;
調(diào)用getCameraAbility(String cameraId)方法查詢相機(jī)能力信息(比如支持的分辨率列表等)。
CameraInfo的主要接口
接口名 |
描述 |
---|---|
getDeviceLinkType?(String physicalId) |
獲取物理相機(jī)連接方式。 |
getFacingType?() |
獲取相機(jī)朝向信息。 |
getLogicalId?() |
獲取邏輯相機(jī)ID。 |
getPhysicalIdList?() |
獲取對(duì)應(yīng)的物理相機(jī)ID列表。 |
CameraAbility的主要接口
接口名 |
描述 |
---|---|
getSupportedSizes?(int format) |
根據(jù)格式查詢輸出圖像的分辨率列表。 |
getSupportedSizes?(Class<T> clazz) |
根據(jù)Class類型查詢分辨率列表。 |
getParameterRange?(ParameterKey.Key<T> parameter) |
獲取指定參數(shù)能夠設(shè)置的值范圍。 |
getPropertyValue?(PropertyKey.Key<T> property) |
獲取指定屬性對(duì)應(yīng)的值。 |
getSupportedAeMode?() |
獲取當(dāng)前相機(jī)支持的自動(dòng)曝光模式。 |
getSupportedAfMode?() |
獲取當(dāng)前相機(jī)支持的自動(dòng)對(duì)焦模式。 |
getSupportedFaceDetection?() |
獲取相機(jī)支持的人臉檢測(cè)類型范圍。 |
getSupportedFlashMode?() |
當(dāng)前相機(jī)支持的閃光燈取值范圍。 |
getSupportedParameters?() |
當(dāng)前相機(jī)支持的參數(shù)設(shè)置。 |
getSupportedProperties?() |
獲取當(dāng)前相機(jī)的屬性列表。 |
getSupportedResults?() |
獲取當(dāng)前相機(jī)支持的參數(shù)設(shè)置可返回的結(jié)果列表。 |
getSupportedZoom?() |
獲取相機(jī)支持的變焦范圍。 |
3.?通過createCamera(String cameraId, CameraStateCallback callback, EventHandler handler)方法,創(chuàng)建相機(jī)對(duì)象,此步驟執(zhí)行成功意味著相機(jī)系統(tǒng)的硬件已經(jīng)完成了上電。
// 前置相機(jī)類型
int frontCamera = CameraInfo.FacingType.CAMERA_FACING_FRONT;
// 后置相機(jī)類型
int backCamera = CameraInfo.FacingType.CAMERA_FACING_BACK;
// 其他相機(jī)類型
int otherCamera = CameraInfo.FacingType.CAMERA_FACING_OTHERS;
// 選擇想要?jiǎng)?chuàng)建的相機(jī)類型,如果不存在該類型相機(jī),則返回false
boolean isCameraCreated = openCameraByFacingType(frontCamera);
// 根據(jù)類型創(chuàng)建相機(jī)的方法
private boolean openCameraByFacingType(int facingType) {
CameraKit cameraKit = CameraKit.getInstance(getApplicationContext());
for(String cameraId : cameraKit.getCameraIds()) {
CameraInfo cameraInfo = cameraKit.getCameraInfo(cameraId);
if(facingType == cameraInfo.getFacingType()) {
cameraKit.createCamera(cameraId, cameraStateCallback, eventHandler);
return true;
}
}
return false;
}
參數(shù)cameraId可以是上一步獲取的邏輯相機(jī)列表中的任何一個(gè)相機(jī)ID。
第二和第三個(gè)參數(shù)負(fù)責(zé)相機(jī)創(chuàng)建和相機(jī)運(yùn)行時(shí)的數(shù)據(jù)和狀態(tài)檢測(cè),請(qǐng)務(wù)必保證在整個(gè)相機(jī)運(yùn)行周期內(nèi)有效。
private final class CameraStateCallbackImpl extends CameraStateCallback {
@Override
public void onCreated(Camera camera) {
// 創(chuàng)建相機(jī)設(shè)備
}
@Override
public void onConfigured(Camera camera) {
// 配置相機(jī)設(shè)備
}
@Override
public void onPartialConfigured(Camera camera) {
// 當(dāng)使用了addDeferredSurfaceSize配置了相機(jī),會(huì)接到此回調(diào)
}
@Override
public void onReleased(Camera camera) {
// 釋放相機(jī)設(shè)備
}
}
// 相機(jī)創(chuàng)建和相機(jī)運(yùn)行時(shí)的回調(diào)
CameraStateCallbackImpl cameraStateCallback = new CameraStateCallbackImpl();
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
// 執(zhí)行回調(diào)的EventHandler
EventHandler eventHandler = new EventHandler(EventRunner.create("CameraCb"));
至此,相機(jī)設(shè)備的創(chuàng)建已經(jīng)完成。相機(jī)設(shè)備創(chuàng)建成功會(huì)在CameraStateCallback中觸發(fā)onCreated(Camera camera)回調(diào)。在進(jìn)入相機(jī)設(shè)備配置前,請(qǐng)確保相機(jī)設(shè)備已經(jīng)創(chuàng)建成功。否則會(huì)觸發(fā)相機(jī)設(shè)備創(chuàng)建失敗的回調(diào),并返回錯(cuò)誤碼,需要進(jìn)行錯(cuò)誤處理后,重新執(zhí)行相機(jī)設(shè)備的創(chuàng)建。
相機(jī)設(shè)備配置
創(chuàng)建相機(jī)設(shè)備成功后,在CameraStateCallback中會(huì)觸發(fā)onCreated(Camera camera)回調(diào),并且?guī)Щ谻amera對(duì)象,用于執(zhí)行相機(jī)設(shè)備的操作。
當(dāng)一個(gè)新的相機(jī)設(shè)備成功創(chuàng)建后,首先需要對(duì)相機(jī)進(jìn)行配置,調(diào)用configure(CameraConfig)方法實(shí)現(xiàn)配置。相機(jī)配置主要是設(shè)置預(yù)覽、拍照、錄像用到的Surface(詳見ohos.agp.graphics.Surface),沒有配置過Surface,相應(yīng)的功能不能使用。
為了進(jìn)行相機(jī)幀捕獲結(jié)果的數(shù)據(jù)和狀態(tài)檢測(cè),還需要在相機(jī)配置時(shí)調(diào)用setFrameStateCallback(FrameStateCallback, EventHandler)方法設(shè)置幀回調(diào)。
// Surface提供對(duì)象
private SurfaceProvider surfaceProvider;
private void initSurface() {
surfaceProvider = new SurfaceProvider(this);
DirectionalLayout.LayoutConfig params = new DirectionalLayout.LayoutConfig(
ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
surfaceProvider.setLayoutConfig(params);
surfaceProvider.pinToZTop(false);
surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceCallBack());
((ComponentContainer)
findComponentById(ResourceTable.Id_surface_container)).addComponent(surfaceProvider);
}
private FrameStateCallback frameStateCallbackImpl = new FrameStateCallback(){
@Override
public void onFrameStarted(Camera camera, FrameConfig frameConfig, long frameNumber, long timestamp) {
...
}
@Override
public void onFrameProgressed(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
...
}
@Override
public void onFrameFinished(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
...
}
@Override
public void onFrameError(Camera camera, FrameConfig frameConfig, int errorCode, FrameResult frameResult) {
...
}
@Override
public void onCaptureTriggerStarted(Camera camera, int captureTriggerId, long firstFrameNumber) {
...
}
@Override
public void onCaptureTriggerFinished(Camera camera, int captureTriggerId, long lastFrameNumber) {
...
}
@Override
public void onCaptureTriggerInterrupted(Camera camera, int captureTriggerId) {
...
}
};
// 相機(jī)設(shè)備
private Camera cameraDevice;
// 相機(jī)預(yù)覽模板
private Surface previewSurface;
// 相機(jī)配置模板
private CameraConfig.Builder cameraConfigBuilder;
// 圖像幀數(shù)據(jù)接收處理對(duì)象
private ImageReceiver imageReceiver;
private final class CameraStateCallbackImpl extends CameraStateCallback {
@Override
public void onCreated(Camera camera) {
cameraDevice = camera;
previewSurface = surfaceProvider.getSurfaceOps().get().getSurface();
cameraConfigBuilder = camera.getCameraConfigBuilder();
if (cameraConfigBuilder == null) {
HiLog.error(LABEL, "onCreated cameraConfigBuilder is null");
return;
}
// 配置預(yù)覽的Surface
cameraConfigBuilder.addSurface(previewSurface);
// 配置拍照的Surface
cameraConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
// 配置幀結(jié)果的回調(diào)
cameraConfigBuilder.setFrameStateCallback(frameStateCallbackImpl, eventHandler);
try {
// 相機(jī)設(shè)備配置
camera.configure(cameraConfigBuilder.build());
} catch (IllegalArgumentException e) {
HiLog.error(LABEL, "Argument Exception");
} catch (IllegalStateException e) {
HiLog.error(LABEL, "State Exception");
}
}
}
相機(jī)配置成功后,在CameraStateCallback中會(huì)觸發(fā)onConfigured(Camera camera)回調(diào),然后才可以執(zhí)行相機(jī)幀捕獲相關(guān)的操作。
?CameraConfig.Builder的主要接口
接口名 |
描述 |
---|---|
addSurface?(Surface surface) |
相機(jī)配置中增加Surface。 |
build?() |
相機(jī)配置的構(gòu)建類。 |
removeSurface?(Surface surface) |
移除先前添加的Surface。 |
setFrameStateCallback?(FrameStateCallback callback, EventHandler handler) |
設(shè)置用于相機(jī)幀結(jié)果返回的FrameStateCallback和Handler。 |
addDeferredSurfaceSize(Size surfaceSize, Class<T> clazz) |
添加延遲Surface的尺寸、類型。 |
addDeferredSurface(Surface surface)文章來源:http://www.zghlxwxcb.cn/news/detail-498304.html |
設(shè)置延遲的Surface,此Surface的尺寸和類型必須和使用addDeferredSurfaceSize配置的一致。文章來源地址http://www.zghlxwxcb.cn/news/detail-498304.html |
到了這里,關(guān)于HarmonyOS學(xué)習(xí)路之開發(fā)篇—多媒體開發(fā)(相機(jī)開發(fā) 一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!