c-将png图像数据管道传输到feh查看器,而不阻塞调用程序(Linux,C99)



我使用libGD函数gdImagePng(gdImagePtr im,FILE*fs(将PNG图像从我的程序管道传输到图像查看器程序feh。我希望能够显示图像并将控制权返回到调用过程,以便在同一feh窗口中显示更多图像。

我用打开了一个通向feh的管道

FILE* fs = popen("feh -", "w");

("-"命令告诉feh从stdin读取(,然后调用

gdImagePng(im, fs);

以查看图像。图像确实显示在feh中,但直到feh关闭,控制才会返回到调用过程。

是否有任何方法可以强制将控制权返回给调用者,同时保持通向feh进程的管道打开以供后续图像显示?我试过将管道设置为无阻塞,但没有效果。试图用";wb";属性失败。将feh过程指定为";feh-"也不起作用(feh过程似乎无法将数据识别为图像(。

我确实有一个解决办法:feh可能被配置为在磁盘上更改图像时自动重新加载图像,因此我可以用system((调用启动feh,以显示写入临时文件(例如/tmp/tmp.png或/dev/shm/tmp.png(的图像,并重复向该文件写入不同的图像。这是可行的,但相当缓慢和笨拙。

[编辑:这个帖子向我暗示,feh的实现可能根本无法满足我想要实现的目标。]

既然您愿意破解feh,那么有一种简单的方法可以做到这一点。

添加一个选项,提醒feh进入特殊输入模式(例如-p(。

然后,在您的程序中执行:popen("myfeh -p -","w");

-p选项表示数据将以struct(您设计的(作为前缀:

enum cmd {
CMD_NEWIMAGE,                       // new image file
CMD_TERMINATE                       // terminate feh
};
struct control {
enum cmd cmd;                       // command to execute
size_t paylen;                      // payload length
};

程序首先用CMD_NEWFILE和要发送的图像文件的字节长度填充结构,并将其发送到管道。

然后,它发送图像文件数据。

feh读取结构,现在,它知道从管道读取多少(例如paylen(。

它读取图像数据并显示。

CCD_ 10循环等待另一个控制块。

由于feh支持自动重新加载,我们知道它已经有了重新加载自己以拍摄新图像的代码。

完成后,您可以用CMD_TERMINATE发送一条控制消息,告诉feh[优雅地]终止。

您可以根据需要添加其他命令。

如果你做得足够干净,你可以把补丁上游到原始作者那里,他们可能会把它添加到feh中,这样你就不必自己维护它了。

最新更新