|
|
|
@ -17,6 +17,7 @@
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <numeric>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <android/log.h>
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
|
#include <opencv2/core/core.hpp>
|
|
|
|
@ -29,6 +30,55 @@
|
|
|
|
|
#include "DngCreator.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void saveYuvToFile(AImage* image, const std::string& filePath) {
|
|
|
|
|
|
|
|
|
|
int32_t width, height;
|
|
|
|
|
AImage_getWidth(image, &width);
|
|
|
|
|
AImage_getHeight(image, &height);
|
|
|
|
|
|
|
|
|
|
// 获取 YUV 数据
|
|
|
|
|
uint8_t* yPlane = nullptr;
|
|
|
|
|
uint8_t* uPlane = nullptr;
|
|
|
|
|
uint8_t* vPlane = nullptr;
|
|
|
|
|
int yLength, uLength, vLength;
|
|
|
|
|
|
|
|
|
|
AImage_getPlaneData(image, 0, &yPlane, &yLength); // Y 分量
|
|
|
|
|
AImage_getPlaneData(image, 1, &uPlane, &uLength); // U 分量
|
|
|
|
|
AImage_getPlaneData(image, 2, &vPlane, &vLength); // V 分量
|
|
|
|
|
|
|
|
|
|
int32_t yStride, uStride, vStride;
|
|
|
|
|
AImage_getPlaneRowStride(image, 0, &yStride); // Y 分量的 Stride
|
|
|
|
|
AImage_getPlaneRowStride(image, 1, &uStride); // U 分量的 Stride
|
|
|
|
|
AImage_getPlaneRowStride(image, 2, &vStride); // V 分量的 Stride
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 打开文件
|
|
|
|
|
std::ofstream file(filePath, std::ios::binary);
|
|
|
|
|
if (!file.is_open()) {
|
|
|
|
|
// 文件打开失败
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 写入 Y 分量(逐行复制,处理 Stride)
|
|
|
|
|
for (int i = 0; i < height; i++) {
|
|
|
|
|
file.write(reinterpret_cast<const char*>(yPlane + i * yStride), width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 写入 U 分量(逐行复制,处理 Stride)
|
|
|
|
|
for (int i = 0; i < height / 2; i++) {
|
|
|
|
|
file.write(reinterpret_cast<const char*>(uPlane + i * uStride), width / 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 写入 V 分量(逐行复制,处理 Stride)
|
|
|
|
|
for (int i = 0; i < height / 2; i++) {
|
|
|
|
|
file.write(reinterpret_cast<const char*>(vPlane + i * vStride), width / 2);
|
|
|
|
|
}
|
|
|
|
|
// 关闭文件
|
|
|
|
|
file.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
void Auto_AImage_delete(AImage* image)
|
|
|
|
|
{
|
|
|
|
@ -1327,6 +1377,16 @@ void NdkCamera::onImageAvailable(AImageReader* reader)
|
|
|
|
|
|
|
|
|
|
int64_t frameTs = 0;
|
|
|
|
|
mstatus = AImage_getTimestamp(image, &frameTs);
|
|
|
|
|
|
|
|
|
|
#ifdef OUTPUT_DBG_INFO
|
|
|
|
|
if (mWidth == 1920)
|
|
|
|
|
{
|
|
|
|
|
std::string dt = FormatLocalDateTime("%d%02d%02d%02d%02d%02d", time(NULL));
|
|
|
|
|
std::string fileName = "/sdcard/com.xypower.mpapp/tmp/" + dt;
|
|
|
|
|
fileName += "_" + mCameraId + std::to_string(frameTs) + ".yuv";
|
|
|
|
|
saveYuvToFile(image, fileName.c_str());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
AImage_delete(image);
|
|
|
|
|
|
|
|
|
|
bool captureCompleted = false;
|
|
|
|
@ -1926,6 +1986,8 @@ void NdkCamera::FireOneCapture(uint64_t ts)
|
|
|
|
|
cv::imwrite(fileName, it->second, params);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
onOneCapture(mCharacteristics, mCaptureResults.back(), mFinalLdr, ts - m_startTime, mOneFrame.back().second);
|
|
|
|
|
}
|
|
|
|
|