|
|
@@ -1,4 +1,5 @@
|
|
|
#include "takephoto.h"
|
|
|
+#include "stb_image_write.h"
|
|
|
|
|
|
// 模块名称
|
|
|
static const char MODULE_NAME[] = "HrTakePhoto";
|
|
|
@@ -34,7 +35,7 @@ typedef struct
|
|
|
int expStableCnt; // 连续曝光稳定帧计数
|
|
|
HANDLE hESig; // 任务结束的通知
|
|
|
int rCode; // 任务结束返回值
|
|
|
- void *pUser; // 附加的用户数据
|
|
|
+ void *pUser; // 可选的用户数据
|
|
|
} PthotoProcCtx;
|
|
|
|
|
|
// 非标准的"Huaray Technology"制造商名称, 但也可视为华睿的
|
|
|
@@ -80,6 +81,7 @@ static void OnFrameReceived(IMV_Frame *pFrame, void *pUser) // 数
|
|
|
}
|
|
|
|
|
|
// 3, 导出图像文件
|
|
|
+ if(ctx->pUser) { sw_thrd_destroy(ctx->pUser, WAITTHRD_SAFEEXIT_TIMEOUT); ctx->pUser = NULL; }
|
|
|
ret = SavePhoto(ctx->hCam, pFrame, ctx->saveImgType, ctx->saveImgPath);
|
|
|
|
|
|
// 4, 设置拍照完成
|
|
|
@@ -249,7 +251,7 @@ waitp:
|
|
|
sw_log_error("[%s] 拍照过程-等待超时!!", MODULE_NAME);
|
|
|
}
|
|
|
|
|
|
- if(hThrd) sw_thrd_destroy(hThrd, WAITTHRD_SAFEEXIT_TIMEOUT);
|
|
|
+ if(ctx.pUser) sw_thrd_destroy(ctx.pUser, WAITTHRD_SAFEEXIT_TIMEOUT);
|
|
|
sw_signal_destroy(ctx.hESig);
|
|
|
|
|
|
// 5, 成功拍照, 输出相机的信息
|
|
|
@@ -277,14 +279,74 @@ end_p:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-// 保存给定的数据帧到BMP图像文件, 成功返回:true, 失败返回:false
|
|
|
-static bool SaveFrameToBmp(IMV_HANDLE hCam, IMV_Frame *pFrame, const char *path)
|
|
|
+// 保存给定的数据帧到BMP图像文件, 成功返回: 0值, 失败返回: 非0值
|
|
|
+static int SaveFrameToBmp(IMV_HANDLE hCam, IMV_Frame *pFrame, const char *path)
|
|
|
{
|
|
|
+ IMV_PixelConvertParam stPixelConvertParam; int ret = IMV_OK;
|
|
|
+ unsigned char *pDstBuf = NULL; unsigned int nDstBufSize = 0;
|
|
|
+
|
|
|
+ nDstBufSize = sizeof(unsigned char) * pFrame->frameInfo.width * pFrame->frameInfo.height * 3;
|
|
|
+ pDstBuf = (unsigned char*)malloc(nDstBufSize);
|
|
|
+ if(!pDstBuf) return -18;
|
|
|
+
|
|
|
+ memset(&stPixelConvertParam, 0, sizeof(stPixelConvertParam));
|
|
|
+ stPixelConvertParam.nWidth = pFrame->frameInfo.width;
|
|
|
+ stPixelConvertParam.nHeight = pFrame->frameInfo.height;
|
|
|
+ stPixelConvertParam.ePixelFormat = pFrame->frameInfo.pixelFormat;
|
|
|
+ stPixelConvertParam.pSrcData = pFrame->pData;
|
|
|
+ stPixelConvertParam.nSrcDataLen = pFrame->frameInfo.size;
|
|
|
+ stPixelConvertParam.nPaddingX = pFrame->frameInfo.paddingX;
|
|
|
+ stPixelConvertParam.nPaddingY = pFrame->frameInfo.paddingY;
|
|
|
+ stPixelConvertParam.eBayerDemosaic = demosaicNearestNeighbor;
|
|
|
+ stPixelConvertParam.eDstPixelFormat = gvspPixelRGB8;
|
|
|
+ stPixelConvertParam.pDstBuf = pDstBuf;
|
|
|
+ stPixelConvertParam.nDstBufSize = nDstBufSize;
|
|
|
+
|
|
|
+ ret = IMV_PixelConvert(hCam, &stPixelConvertParam);
|
|
|
+ if(IMV_OK != ret) goto ret_p;
|
|
|
+
|
|
|
+ ret = stbi_write_bmp(path, pFrame->frameInfo.width, pFrame->frameInfo.height, 3, pDstBuf);
|
|
|
+ if(1 == ret) ret = IMV_OK;
|
|
|
+ else ret = -19;
|
|
|
+
|
|
|
+ret_p:
|
|
|
+ if(pDstBuf) free(pDstBuf);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
-// 保存给定的数据帧到JPG图像文件, 成功返回:true, 失败返回:false
|
|
|
-static bool SaveFrameToJpg(IMV_HANDLE hCam, IMV_Frame *pFrame, const char *path)
|
|
|
+// 保存给定的数据帧到JPG图像文件, 成功返回: 0值, 失败返回: 非0值
|
|
|
+static int SaveFrameToJpg(IMV_HANDLE hCam, IMV_Frame *pFrame, const char *path)
|
|
|
{
|
|
|
+ IMV_PixelConvertParam stPixelConvertParam; int ret = IMV_OK;
|
|
|
+ unsigned char *pDstBuf = NULL; unsigned int nDstBufSize = 0;
|
|
|
+
|
|
|
+ nDstBufSize = sizeof(unsigned char) * pFrame->frameInfo.width * pFrame->frameInfo.height * 3;
|
|
|
+ pDstBuf = (unsigned char*)malloc(nDstBufSize);
|
|
|
+ if(!pDstBuf) return -18;
|
|
|
+
|
|
|
+ memset(&stPixelConvertParam, 0, sizeof(stPixelConvertParam));
|
|
|
+ stPixelConvertParam.nWidth = pFrame->frameInfo.width;
|
|
|
+ stPixelConvertParam.nHeight = pFrame->frameInfo.height;
|
|
|
+ stPixelConvertParam.ePixelFormat = pFrame->frameInfo.pixelFormat;
|
|
|
+ stPixelConvertParam.pSrcData = pFrame->pData;
|
|
|
+ stPixelConvertParam.nSrcDataLen = pFrame->frameInfo.size;
|
|
|
+ stPixelConvertParam.nPaddingX = pFrame->frameInfo.paddingX;
|
|
|
+ stPixelConvertParam.nPaddingY = pFrame->frameInfo.paddingY;
|
|
|
+ stPixelConvertParam.eBayerDemosaic = demosaicNearestNeighbor;
|
|
|
+ stPixelConvertParam.eDstPixelFormat = gvspPixelRGB8;
|
|
|
+ stPixelConvertParam.pDstBuf = pDstBuf;
|
|
|
+ stPixelConvertParam.nDstBufSize = nDstBufSize;
|
|
|
+
|
|
|
+ ret = IMV_PixelConvert(hCam, &stPixelConvertParam);
|
|
|
+ if(IMV_OK != ret) goto ret_p;
|
|
|
+
|
|
|
+ ret = stbi_write_jpg(path, pFrame->frameInfo.width, pFrame->frameInfo.height, 3, pDstBuf, 90);
|
|
|
+ if(1 == ret) ret = IMV_OK;
|
|
|
+ else ret = -19;
|
|
|
+
|
|
|
+ret_p:
|
|
|
+ if(pDstBuf) free(pDstBuf);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
// 保存给定的数据帧到指定格式("BMP"/"JPG")的图像文件,成功返回0值
|
|
|
@@ -310,14 +372,14 @@ static int SavePhoto(HANDLE hCam, IMV_Frame *pFrame, DHImgType imgType, const ch
|
|
|
path2 = (char *)sw_heap_malloc(strlen(path1) + sizeof(ext));
|
|
|
if(path2) sprintf(path2, "%s%s", path1, ext);
|
|
|
else return -17;
|
|
|
- if(imgType == IMG_TYPE_BMP && !SaveFrameToBmp(hCam, pFrame, path2)) ret = -18;
|
|
|
- if(imgType == IMG_TYPE_JPG && !SaveFrameToJpg(hCam, pFrame, path2)) ret = -19;
|
|
|
+ if(imgType == IMG_TYPE_BMP) ret = SaveFrameToBmp(hCam, pFrame, path2);
|
|
|
+ if(imgType == IMG_TYPE_JPG) ret = SaveFrameToJpg(hCam, pFrame, path2);
|
|
|
sw_heap_free(path2);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- if(imgType == IMG_TYPE_BMP && !SaveFrameToBmp(hCam, pFrame, path1)) ret = -18;
|
|
|
- if(imgType == IMG_TYPE_JPG && !SaveFrameToJpg(hCam, pFrame, path1)) ret = -19;
|
|
|
+ if(imgType == IMG_TYPE_BMP) ret = SaveFrameToBmp(hCam, pFrame, path1);
|
|
|
+ if(imgType == IMG_TYPE_JPG) ret = SaveFrameToJpg(hCam, pFrame, path1);
|
|
|
}
|
|
|
|
|
|
return ret;
|