Quellcode durchsuchen

完善大华相机拍照模块代码, 保存采集到的数据帧到bmp或jpg文件

niujiuru vor 3 Wochen
Ursprung
Commit
5dc90f48b6
4 geänderte Dateien mit 1799 neuen und 11 gelöschten Zeilen
  1. 1 1
      dh_takephoto/Makefile
  2. 2 0
      dh_takephoto/stb_image_write.c
  3. 1724 0
      dh_takephoto/stb_image_write.h
  4. 72 10
      dh_takephoto/takephoto.c

+ 1 - 1
dh_takephoto/Makefile

@@ -7,7 +7,7 @@ INCS += -I./include
 
 # 源文件
 SRCS += $(filter-out ../swapi/testLib.c, $(wildcard ../swapi/*.c))
-SRCS += takephoto.c
+SRCS += takephoto.c stb_image_write.c
 
 # .o文件
 OBJS := $(SRCS:.c=.o)

+ 2 - 0
dh_takephoto/stb_image_write.c

@@ -0,0 +1,2 @@
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "stb_image_write.h"

Datei-Diff unterdrückt, da er zu groß ist
+ 1724 - 0
dh_takephoto/stb_image_write.h


+ 72 - 10
dh_takephoto/takephoto.c

@@ -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;