c++ - 动画 gif 上的 ImageMagick 文本水印

标签 c++ image imagemagick gif

//add text watermark on animated gif
std::vector<Image> imglist;
std::vector<Drawable> text_list;
text_list.push_back( DrawableText(0, 0, “I love you!"));
text_list.push_back( DrawableStrokeColor(Color("black")));
try {
    readImages(&imglist, "test.gif");
    for (uint32_t i = 0; i < imglist.size(); ++i) {
        imglist[i].font("./MILT_RG.ttf");
        imglist[i].draw(text_list);
    }
    writeImages(imglist.begin(), imglist.end(), "test_render.gif");
} catch (Exception &error_) {

    cout << error_.what() << endl;
}

但是 writeImages 函数花费了太多时间。在我的测试示例中,一个 gif,900x600,20 帧,需要 1.5 秒。有什么解决方案可以加快速度吗?或者,一些更好的算法在 gif 上添加文本水印。谢谢。

最佳答案

您可以利用 STL 来简化事情

std::vector<Image> imglist;
DrawableList text_list; // <= Same as vector<Drawable>
text_list.push_back( DrawableText(0, 0, "I love you!"));
text_list.push_back( DrawableStrokeColor(Color("black")));
try {
    readImages(&imglist, "test.gif");
    for_each(imglist.begin(), imglist.end(), fontImage("./MILT_RG.ttf"));
    for_each(imglist.begin(), imglist.end(), drawImage(text_list));
    writeImages(imglist.begin(), imglist.end(), "test_render.gif");
} // ...

但是由于您对速度更感兴趣,可能是时候考虑使用 OpenMP 进行并行处理了.

#pragma omp parallel for
for (size_t i = 0; i < imglist.size(); ++i) {
    imglist[i].font("./MILT_RG.ttf");
    imglist[i].draw(text_list);
}

最后,您可以将字体移动到可绘制上下文中,并消除重复读取同一个 TTF 文件。可能是最好的选择。

std::vector<Image> imglist;
DrawableList text_list;
text_list.push_back( DrawableFont("./MILT_RG.ttf"));
text_list.push_back( DrawableText(32, 32, "I love you!"));
text_list.push_back( DrawableStrokeColor(Color("black")));
try {
    readImages(&imglist, "test.gif");
    for_each(imglist.begin(), imglist.end(), drawImage(text_list));
    writeImages(imglist.begin(), imglist.end(), "test_render.gif");
} // ...

YMMV

编辑

正如 Mark 在评论中指出的那样,在临时图像中绘制一次文本并跨所有帧进行合成可能会更快。

Geometry imgSize = imglist[0].size();
Image imgText(imgSize, Color("transparent"));
imgText.draw(text_list);
for_each(imglist.begin(), imglist.end(), compositeImage(imgText, 0, 0, AtopCompositeOp)); 

关于c++ - 动画 gif 上的 ImageMagick 文本水印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45455596/

相关文章:

c++ - substr 的错误输出

image - 使用 rmagick 像在 Photoshop 中一样为图像着色

c++ - Magick++ 使用 CGI 显示图像

c++ - Xcode 11.1 : iostream' file not found

c++ - 通过 OpenSSL (c++) 以 XML (w3c) 格式保存 RSA 公钥和私钥

cocoa - 如何设置图像透视

image - ActionMailer 电子邮件图像在某些客户端中损坏

django - 无法使用 ImageField 在 django 中上传图像

video - 如何使用 ffmpeg 或 imagemagick 将两个图像序列与 alpha channel 批量组合?

c++ - Mac 和 Windows 区别头文件路径(/vs\)