ImageMagick动画gif上的文字水印

时间:2017-08-02 08:33:07

标签: 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上添加文本水印。感谢。

2 个答案:

答案 0 :(得分:1)

您可以通过利用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

修改

正如马克在评论中所指出的那样,将文本用临时图像绘制一次&amp;跨所有帧合成可能会更快。

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)); 

答案 1 :(得分:0)

我发现了一种可能的方法。我们可以根据@emcconville的上述答案来并行化程序。但我们必须并行化成本操作,即量化。这是代码:

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