在 C++ 中修改位图时流式传输位图

streaming a bitmap while it is modified in C++

我想做的是使用一些过程来改变位图图像的内容(尺寸和其他一切都保持不变)。当我 运行 一个对其执行转换的过程时,我想同时将图像流式传输到我的屏幕上。所以它基本上是没有一系列图像的视频,而是处于不同转换阶段的同一图像。 我正在尝试这样做,因为我想要执行此操作的位图很大,因此实际上将每个状态保存为自己的图像,然后由于内存限制而无法合并。

我的问题是关于 "live image display" 当另一个进程修改图像时,有什么方法可以用位图图像完成这样的事情吗?

您可以直接在视频编码器中流式传输图像。

例如,您可以将原始 PGM/PPM 图像作为输入提供给 ffmpeg,您将获得压缩视频作为输出,而无需在磁盘上创建实际图像。

编写 PGM 或 PPM 图像意味着只需生成几个 header 字节后跟实际像素值,因此无需任何图像库即可使用任何语言轻松完成。例如:

#include <stdio.h>
#include <math.h>
#include <algorithm>

int main(int argc, const char *argv[]) {
    int w = 1920, h = 1080;
    for (int frame=0; frame<100; frame++) {
        // output frame header
        printf("P5\n%i %i 255\n", w, h);
        for (int y=0; y<h; y++) {
            for (int x=0; x<w; x++) {
                double dx = (x - w/2),
                       dy = (y - h/2),
                       d = sqrt(dx*dx + dy*dy),
                       a = atan2(dy, dx) - frame*2*3.14159265359/100,
                       value = 127 + 127*sin(a+d/10);
                // output pixel
                putchar(std::max(0, std::min(255, int(value))));
            }
        }
    }
    return 0;
}

在标准输出上生成一系列可以直接组合到视频中的图像。 运行 程序

./video | ffmpeg -i - -r 60 -format pgm -y out.mp4

将生成一个名为 out.mp4 的视频。视频将以 60fps(-r 的目的)从标准输入(选项 -i -)以 PGM 格式(-format pgm)的源图像创建,如果输出文件已经存在( -y).

此代码已在 linux 上测试;对于这种在 windows 上工作的方法,您还需要使用 _setmode(fileno(stdout), _O_BINARY); 或类似的东西将 stdout 设置为二进制更多(我没有在 windows 上测试)。

基本相同的更复杂的方法是启动一个 child 进程而不是使用管道,从而使程序可以使用标准输出。

如果您只是想实时查看结果,可以使用类似于翻页/双缓冲的方法。

基本上:创建两个图像。图 1 是 "drawing buffer" 而图 2 是 "display buffer." 对图 1 执行绘图的某些部分。然后,将其完整内容复制到图 2。继续绘制图 1,复制、绘制、复制, draw...等。在每次复制之前插入一个延迟。