我如何嵌入图标和视频流

时间:2014-03-13 13:16:33

标签: c# c++ video video-streaming video-capture

我有一些mp4视频文件,我想在这个视频文件中设置一些小图标(可以是简单的位图)。

我想写一些应用程序,输入是mp4 / mpeg文件和一些图标或位图,输出是相同的mp4,这个图标嵌入左角。

怎么做? 是否有一些代码示例?

1 个答案:

答案 0 :(得分:2)

你可以使用很多库来完成这样的事情,我将向你展示一种使用C ++和OpenCV的方法。

你基本上需要做三件事:

  1. 您需要解码输入视频文件
  2. 您需要处理每个框架,以便在角落添加图标/图像
  3. 您需要重新编码已修改的帧,并将其保存到新的视频文件中
  4. OpenCV是一个专门从事图像处理的库。它可以帮助您完成任务#2。它还具有一些允许您读取和写入视频文件的功能,但它不像专门编码/解码视频文件的其他库(如ffmpeg)那样先进。

    我创建了一个使用OpenCV读取视频文件(wmv)的示例,并向每个帧添加一个图像文件(jpg)。结果将是另一个视频文件(avi)。 OpenCV也可以读取其他类型的视频文件(mp4),但我无法保存.mp4文件,我只能保存.avi文件。

    为了使用我的示例,您需要在您的平台和所选IDE中设置OpenCV。您可以在OpenCV website上找到有关如何执行此操作的信息。

    在我的示例中,我使用MJPEG编码器保存视频文件。如果您将CV_FOURCC('M','J','P','G')替换为-1,则会弹出一个窗口,询问您要使用的编码器。如果您想使用其他编码器,只需将-1放在那里。

    以下是我使用的代码:

    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    void addImageInCorner(Mat videoFrame, Mat resizedImage)
    {
        // The destination location of the image in the frame (upper-left corner)
        Rect destinationRect(0, 0, resizedImage.cols, resizedImage.rows);
        // Copy the image to the specified location in the frame
        resizedImage.copyTo(videoFrame(destinationRect));
    }
    
    void main()
    {
        string inputVideoFile = "C:\\Users\\Public\\Videos\\Sample Videos\\Wildlife.wmv";
        string inputImageFile = "C:\\Users\\Public\\Pictures\\Sample Pictures\\Koala.jpg";
        string outputVideoFile = "C:\\Users\\Public\\Videos\\Sample Videos\\output.avi";
    
        // Read image file
        Mat image = imread(inputImageFile);
        Mat resizedImage;
        resize(image, resizedImage, Size(400, 300));
    
        // Open video capture
        VideoCapture capture;
        capture.open(inputVideoFile);
    
        if (!capture.isOpened())
        {
            return;
        }
    
        // Get the capture properties
        double fps = capture.get(CV_CAP_PROP_FPS);
        int videoWidth = capture.get(CV_CAP_PROP_FRAME_WIDTH);
        int videoHeight = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
    
        // Initialize the video writer
        VideoWriter writer;
        writer.open(outputVideoFile, CV_FOURCC('M','J','P','G'), fps, Size(videoWidth, videoHeight));
    
        Mat currentFrame;
        namedWindow("video");
    
        // While the window is still open
        while (cvGetWindowHandle("video") != NULL)
        {
            // Read the next frame
            capture >> currentFrame;
    
            if (currentFrame.empty())
            {
                // If the frame could not be read, exit the loop
                break;
            }
    
            // Add the image to the corner of the video frame
            addImageInCorner(currentFrame, resizedImage);
    
            writer << currentFrame;
    
            // Show the image in the video window
            imshow("video", currentFrame);
            waitKey(10);
        }
    
        writer.release();
    }
    

    以下是生成的图片: Result image frame

    我希望这会对你有所帮助。