视频预览

今天解决录像相关事宜。

  1. 需求

首先来说一下使用需求,在使用过程中,有以下几种状态:

  1. 视频预览状态:使用前,用户可以进行录像工作、播放视频文件工作

  1. 正常录像状态:录像过程中,用户可以暂停录像、停止录像

  1. 暂停录像状态:在暂停状态下,用户可以继续录像、停止录像

其次,状态切换操作:

起始状态

用户操作

结束状态

视频预览状态

录像操作

正常录像状态

正常录像状态

暂停操作

暂停录像状态

停止操作

视频预览状态

暂停录像状态

继续操作

正常录像状态

停止操作

视频预览状态

  1. 设计

    1. 状态处理

先设计状态类型:

enum TRecordingStatus { // 视频录制状态

    rsNormal,     // 视频预览状态

    rsRecord,         //正常录像状态

    rsPause         //暂停录像状态

};

    TRecordingStatus FRecordingStatus;

 

    __property TRecordingStatus RecordingStatus = {

        read = FRecordingStatus, write = SetRecordingStatus

    };

    void __fastcall SetRecordingStatus(TRecordingStatus value);

 

 

void __fastcall TMainForm::SetRecordingStatus(TRecordingStatus value) {

    FRecordingStatus = value;

    if (FRecordingStatus == rsRecord) { // 录制状态

        Button_Record->LargeImageIndex = 72;

        Button_Record->ImageIndex = 84;

        Button_Record->Caption = "暂停";

        Button_Play->LargeImageIndex = 73;

        Button_Play->ImageIndex = 85;

        Button_Play->Caption = "停止";

    }

    else if (FRecordingStatus == rsPause) {

        Button_Record->LargeImageIndex = 71;

        Button_Record->ImageIndex = 78;

        Button_Record->Caption = "继续";

        Button_Play->LargeImageIndex = 73;

        Button_Play->ImageIndex = 85;

        Button_Play->Caption = "停止";

    }

    else if (FRecordingStatus == rsNormal) {

        Button_Record->LargeImageIndex = 70;

        Button_Record->ImageIndex = 77;

        Button_Record->Caption = "录像";

        Button_Play->LargeImageIndex = 71;

        Button_Play->ImageIndex = 78;

        Button_Play->Caption = "播放";

    }

}

在实现过程中,发现图标下标确实太乱,大图标与小图标不对应,还需要逐个去找,悲催。有时间整理一下。

大图标:

小图标:

大小图标主要是用于窗口缩放导致主工具栏宽度不一样时,Ribbon会自动缩放按钮进行匹配。

则Button_RecordClick单击按钮事件处理:

    if (FRecordingStatus == rsNormal || FRecordingStatus == rsPause)

        RecordingStatus = rsRecord;

    else if (FRecordingStatus == rsRecord)

        RecordingStatus = rsPause;

Button_PlayClick按钮事件处理:

    if (FRecordingStatus != rsNormal) // 非正常状态,即为录像相关状态,停止

        VideoGrabber->Stop();

    else // 播放视频文件

  1. 录像

录像首先确定目标文件名

         UnicodeString path = OptionForm->Edit_SavePath->Text;

         if (!THelper::IsEndWith(path, "\\"))

         path += "\\";

         TFrameCaptureDest destFormat = OptionForm->ComboBox_Format->ItemIndex == 0 ? fc_BmpFile : fc_JpegFile;

         UnicodeString destFileName = "";

         int index = 0;

         do {

         ++index;

         destFileName = THelper::FormatString("%svideo%d.asf", path.w_str(), index);

         }

         while (FileExists(destFileName));

 

发现该代码段用过多次,干脆设计为一个函数:

UnicodeString __fastcall THelper::NextExpectedFileName(UnicodeString path, UnicodeString baseFileName, UnicodeString extName) {

// 得到指定路径下的期望文件名称

        if (!THelper::IsEndWith(path, "\\"))

            path += "\\";

        if(!THelper::IsStartWith(extName, "."))

            extName = "." + extName;

        UnicodeString destFileName = "";

        int index = 0;

        do {

            ++index;

            destFileName = THelper::FormatString("%s%s%d%s", path.w_str(), baseFileName.w_str(), index, extName.w_str());

        }

        while (FileExists(destFileName));

        return destFileName;

}

这样,只需要调用一个函数即可:

UnicodeString destFileName = THelper::NextExpectedFileName(OptionForm->Edit_SavePath->Text, L"video", L"asf");

录像的代码很简单,暂停、停止的功能也很好实现

  1. 缩放

上次在一所学校演示时,那时的老师提出了一个需求:能否在录像的同时,可以拖动、缩放。

这话说起来很简单,得实现哈。

花了整整一上午实现了这个功能的一半,汗!

翻来覆去地组合控件的各个属性:AdjustPixelAspectRatio、Display_AutoSize、Display_AspectRatio、Cropping_Zoom、Cropping_X、Cropping_Y、ZoomCoeff。最后靠把Inspector放在程序里进行手动调整达到预期效果。

设计使用方法:

之前,鼠标左键按下可拖动

而滚轮可缩放:

也就是说,缩放与拖动是整体式的。

现在需要外围不动,而内部内容变化。从操作角度而言,可以让用户按下Ctrl键再进行鼠标操作,比如原始视频:

Ctrl+滚轮进行内部缩放:

Ctrl+鼠标左键拖动内部:

原文地址:https://www.cnblogs.com/drgraph/p/3060829.html