首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

OpenCV 視頻寫入:cvCreateVideoWriter 文件名動態生成(時間戳)的正確姿勢

     編輯:程式設計疑難解答

問題代碼缺陷

char *getSystemTime() {
    char y[20], mon[5], d[5], h[5], mins[5], *temp;
    char str[5]=".avi"; // 危險:str 太小,strcat 會溢出
    // ... itoa/strcat 拼接 ...
    return temp; // 返回棧上數組指針,函數返回即失效 → 未定義行為
}

核心錯誤

  1. 返回局部棧數組指針:`y`、`str` 都是棧內存,函數結束自動釋放,調用者拿到野指針。
  2. 緩衝區溢出:`char str[5]` 只能放 4 字符 + `\0`,`strcat(y, str)` 寫入超出邊界。
  3. `itoa` 非標準:MSVC 支援,跨平台請用 `snprintf`。

正解:靜態緩衝區 / 動態分配 / 傳出參數

方案一:靜態緩衝區(簡單、單線程安全)

const char* getSystemTime() {
    static char buf[64]; // 靜態存儲區,生命周期至程序結束
    SYSTEMTIME st;
    GetSystemTime(&st); // Windows API,跨平台用 time()/localtime()
    snprintf(buf, sizeof(buf), "%04d%02d%02d_%02d%02d%02d.avi",
             st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    return buf;
}

// 調用
CvVideoWriter* writer = cvCreateVideoWriter(getSystemTime(),
    CV_FOURCC('M','J','P','G'), fps, cvSize(w,h), 1);

方案二:傳出參數(最通用、線程安全)

void getSystemTime(char* outBuf, size_t bufSize) {
    SYSTEMTIME st; GetSystemTime(&st);
    snprintf(outBuf, bufSize, "%04d%02d%02d_%02d%02d%02d.avi",
             st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
}

// 調用
char filename[64];
getSystemTime(filename, sizeof(filename));
writer = cvCreateVideoWriter(filename, ...);

方案三:C++17 `std::filesystem` + `chrono`(現代、跨平台)

#include 
#include 
#include 

std::string makeTimestampFilename() {
    auto now = std::chrono::system_clock::now();
    auto t = std::chrono::system_clock::to_time_t(now);
    std::tm tm = *std::localtime(&t);
    char buf[64];
    std::strftime(buf, sizeof(buf), "%Y%m%d_%H%M%S.avi", &tm);
    return std::string(buf);
}

// 用 cv::VideoWriter (C++ API, 推薦)
cv::VideoWriter writer(makeTimestampFilename(),
    cv::VideoWriter::fourcc('M','J','P','G'), fps, cv::Size(w,h), true);

關鍵提示

  • 編碼器 `CV_FOURCC('M','J','P','G')` (MJPEG) 兼容性最好;`'P','I','M','1'` (MPEG-1) 某些系統無解碼器。
  • 檢查 `writer.isOpened()` 確認創建成功。
  • 寫入幀前確保 `pFrame` 非空、尺寸匹配、通道數一致(彩色 3 通道、灰度 1 通道)。

**告別棧指針返回、緩衝區溢出、非標準函數,用 `snprintf` + 靜態/傳出緩衝區,或直接拥抱 C++17 `` + `cv::VideoWriter`。**

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved