使用 C++ 中的 Android NDK 拍照(无 JNI)

问题描述 投票:0回答:1

我正在编写一个简单的 NDK 应用程序,它应该使用相机拍照,而无需通过 JNI。

我已经使用ACameraManager_openCamera成功打开相机并获取了相机特征(ACameraManager_getCameraCharacteristics),但我不知道如何拍照。

我发现的所有示例都需要从 Java 层传递 surface。我不想这样做,想要一个仅使用 NDK 的 100% C++ 应用程序。

该应用程序将在专用的 root 设备上运行。

android c++ android-ndk
1个回答
0
投票

嗨,我不确定你所说的 100% 仅 C++ 到底是什么意思,但你最好的选择是使用 Native Activity 构建应用程序。 https://developer.android.com/ndk/reference/group/native-activity github 示例位于 https://github.com/android/ndk-samples,称为本机活动。

关于跳过 Java/Kotlin 的表面,最好的选择是使用 AImageReader https://developer.android.com/reference/android/media/ImageReader (该文档适用于 Java 版本,应该与功能(如果与 AImageReader 不同)。据我了解,AImageReader可以让你在CPU端高效地传输图像。

基于这个demo https://github.com/sixo/native-camera/blob/master/app/src/main/cpp/native-lib.cpp,可以看到可以从图像阅读器。

#ifdef WITH_IMAGE_READER
static void imageCallback(void* context, AImageReader* reader)
{
    AImage *image = nullptr;
    auto status = AImageReader_acquireNextImage(reader, &image);
    LOGD("imageCallback()");
    // Check status here ...

    // Try to process data without blocking the callback
    std::thread processor([=](){

        uint8_t *data = nullptr;
        int len = 0;
        AImage_getPlaneData(image, 0, &data, &len);

        // Process data here
        // ...

        AImage_delete(image);
    });
    processor.detach();
}

AImageReader* createJpegReader()
{
    AImageReader* reader = nullptr;
    media_status_t status = AImageReader_new(640, 480, AIMAGE_FORMAT_JPEG,
                     4, &reader);

    //if (status != AMEDIA_OK)
        // Handle errors here

    AImageReader_ImageListener listener{
            .context = nullptr,
            .onImageAvailable = imageCallback,
    };

    AImageReader_setImageListener(reader, &listener);

    return reader;
}

ANativeWindow* createSurface(AImageReader* reader)
{
    ANativeWindow *nativeWindow;
    AImageReader_getWindow(reader, &nativeWindow);

    return nativeWindow;
}
#endif


ACaptureSessionOutputContainer_create(&outputs);

#ifdef WITH_IMAGE_READER
    imageReader = createJpegReader();
    imageWindow = createSurface(imageReader);
    ANativeWindow_acquire(imageWindow);
    ACameraOutputTarget_create(imageWindow, &imageTarget);
    ACaptureRequest_addTarget(request, imageTarget);
    ACaptureSessionOutput_create(imageWindow, &imageOutput);
    ACaptureSessionOutputContainer_add(outputs, imageOutput);
#endif

    // Create the session
    ACameraDevice_createCaptureSession(cameraDevice, outputs, &sessionStateCallbacks, &textureSession);

    // Start capturing continuously
    ACameraCaptureSession_setRepeatingRequest(textureSession, &captureCallbacks, 1, &request, nullptr);

如您所见,您可以在没有任何 openGL 界面的情况下进行完整的会话,大多数示例都使用它,因为在屏幕上查看预览很有用,但我想这不是必需的。

好吧,说实话我还没有尝试过,所以让我们知道效果如何:)

© www.soinside.com 2019 - 2024. All rights reserved.