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

5
我想做的是使用某个进程来更改位图图像的内容(保持尺寸和其他所有内容不变)。在运行进行转换的过程中,我希望可以实时地将图像流式传输到我的屏幕上。因此,这基本上是视频,而不是一系列图像,而是处于转换不同阶段的相同图像。 我尝试这样做是因为我要处理的位图很大,因此由于内存限制,实际上无法保存每个状态作为自己的图像,然后进行组合。

我的问题与“实时图像显示”相关,当另一个进程修改图像时,是否有任何方法可以对位图图像执行此类操作?

2个回答

4
你可以直接在视频编码器中传输图像。
例如,您可以将原始的PGM / PPM图像作为输入提供给ffmpeg,并且无需创建实际的磁盘图像即可获得压缩后的视频作为输出。
编写PGM或PPM图像只需生成一些标头字节,后跟实际像素值,因此可以轻松使用任何语言完成,而不需要任何图像库。例如:
#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的作用)从标准输入中的PGM格式源图像(-format pgm)创建,如果输出文件已经存在,则覆盖它(-y选项)。

此代码在Linux上进行了测试;要使此方法在Windows上正常工作,您还需要将stdout设置为二进制模式,例如_setmode(fileno(stdout), _O_BINARY);或类似内容(我没有在Windows上进行测试)。

执行基本相同任务的更复杂的方法是启动子进程而不是使用管道,从而让程序可以使用标准输出。


1
如果您只是想实时查看结果,可以使用类似翻页/双缓冲的东西。
基本上:创建两个图像。图像1是“绘图缓冲区”,而图像2是“显示缓冲区”。将一些绘图部分执行到图像1中。然后,将其完整内容复制到图像2中。继续在图像1中绘图,复制,绘图,复制...等等。在每次复制之前插入延迟。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接