ImageMagick Magick ++编写gif的速度真的很慢

时间:2018-09-19 21:34:56

标签: c++ multithreading image imagemagick

我使用gdal和Magick ++编写了一个简单的C ++应用程序。 该程序采用了Gdal制作的tiff,并将其添加到Magick gif中。 这个过程确实很慢,大约需要800 MB的ram(只有24帧)...需要15秒 我尝试根据此http://im.snibgo.com/spdsiz.htm优化输入文件,但过程仍然很慢 我正在为Web服务的一部分工作,所以15秒真的太多了

int main(int argc, char *argv[]) {
    //timing for bench
    high_resolution_clock::time_point t1 = high_resolution_clock::now();

    char dirName[12];
    char timestamp[22];

    //takes the args and convert them to tm struct
    tm startDate = toTime(std::stringstream(argv[1]));
    tm endDate = toTime(std::stringstream(argv[2]));
    //calc the time differenze
    int diffHours = (int) std::difftime(timegm(&endDate), timegm(&startDate)) / 3600;
    //register gdal driver and create the datasets
    GDALAllRegister();
    GDALDataset *originalDataset;
    GDALDataset *newDataset;
    //option for the apply color to the tif file and set the alpha
    char *optionForDEM[] = {const_cast<char *>("-alpha"), nullptr};
    GDALDEMProcessingOptions *options = GDALDEMProcessingOptionsNew(optionForDEM, nullptr);

    //read the background and the "alert zones" (za)
    Magick::Image background;
    Magick::Image za;
    background.read("/home/giovanni/CLionProjects/MappeIRPI-CNR/sfondo2.mpc");
    za.read("/home/giovanni/CLionProjects/MappeIRPI-CNR/ZA.mpc");
    //create a vector for create the gif
    //i suspect that this method is really slow
    std::vector<Magick::Image> frames;


    int g;
    time_t date;
    for (int i = 0; i < diffHours; ++i) {
        //start of gdal processing block
        date = timegm(&startDate);
        strftime(dirName, 12, DIR_FORMAT.c_str(), gmtime(&date));
        fs::create_directory(fs::path(TEMP_PATH + dirName));

        originalDataset = (GDALDataset *) GDALOpen((BASE_PATH + dirName + PREVISTE).c_str(), GA_ReadOnly);
        newDataset = (GDALDataset *) GDALDEMProcessing((TEMP_PATH + dirName + PREVISTE).c_str(),
                                                   originalDataset,
                                                   "color-relief",
                                                   COLORI.c_str(), options, &g);
        GDALClose(newDataset); //write the processed tif to ramdisk

        //start of the Magick++ block
        Magick::Image tif;
        //read the block
        tif.read(TEMP_PATH + dirName + PREVISTE);
        tif.scale(Magick::Geometry(1083, 1166));
        //add the background and the za
        //i want to apply that to the final gif, not to every single photo
        tif.composite(background, 0, 0, Magick::DstOverCompositeOp);
        tif.composite(za, 0, 0, Magick::OverCompositeOp);
        //options for annotate the frame
        tif.font("/usr/share/fonts/OTF/SFMono-Bold.otf");
        tif.fillColor("White");
        tif.fontPointsize(37);
        tif.boxColor("Black");
        strftime(timestamp, 22, DATE_FORMAT.c_str(), gmtime(&date));
        tif.annotate(timestamp, Magick::NorthEastGravity);
        //add the frame to the vector add set the animation delay
        frames.push_back(tif);
        tif.animationDelay(3000);

        startDate.tm_hour += 1;
    }

    //write the gif to disk, this takes a very long time
    Magick::writeImages(frames.begin(), frames.end(), TEMP_PATH + "sss.gif");

    GDALClose(originalDataset);
    GDALDEMProcessingOptionsFree(options);

    high_resolution_clock::time_point t2 = high_resolution_clock::now();
    auto duration = duration_cast<seconds>(t2 - t1).count();
    std::cout << duration;

return 0;
}

这是工作流程:

  • 获取tifs
  • 与gdal合作
  • 将文件写为png(更快的格式?)
  • 使用.read读取PNG
  • 用时间戳注释图像
  • 在地图上添加背景和ZA *
  • 将帧添加到图像矢量
  • 写矢量

* i我尝试在收集所有图像之后执行此操作,避免对每个图像执行此操作,但是我做不到。

我尝试将背景转换为2种颜色png,然后转换为miff文件,然后转换为mpc + cache za.png使用alpha和1种颜色,我执行了相同的过程

最快的格式是什么?我还需要gif尽可能少(现在占用5.4 MB !!)

如前所述,操作必须非常快,因此我也可以考虑将其他库更简单...只要解决了这些基本问题,便会诉诸于多线程(任何最佳方法?),但是从我的测试中,最长的阶段是编写磁盘上的gif(上面的虚拟磁盘)

结果样本: https://photos.app.goo.gl/6YVkqSMuoXwMYuE57

Google相册: https://photos.app.goo.gl/QDNCAK4i9PCGQW3VA

编辑 感谢您的快速评论

我正在使用Arch Linux,但最终程序将运行Web服务器,但功能不那么强大 Debian 9.5、4个虚拟内核和8 GB的ram(如果需要,我可以要求改进,但不要太多

必须至少管理24帧,但我什至可以达到700帧... 图像最初占用130KB,但将到达颜色添加到400KB 这是在添加背景并划分区域之前(请参阅Google相册中的图像)

我使用G ++ 8.2.1进行编译 这是cmake文件

cmake_minimum_required(VERSION 3.12)
project(MappeIrpi)
SET(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(SOURCE_FILES main.cpp vips.cpp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp -lstdc++fs")
add_executable(MappeIrpi ${SOURCE_FILES})
FIND_PACKAGE(GDAL COMPONENTS REQUIRED)
add_definitions(-DMAGICKCORE_QUANTUM_DEPTH=8)
add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 )
add_definitions(-fopenmp -pthread)
find_package(ImageMagick COMPONENTS Magick++)
include_directories(${ImageMagick_INCLUDE_DIRS})
target_link_libraries(MappeIrpi ${ImageMagick_LIBRARIES} gdal stdc++fs "/usr/lib/libMagickCore-7.Q16HDRI.so.6")

当前我还没有设置优化标志,但是即使设置-O3或-Ofast也不会更改任何内容

资源限制:

$ identify -list resource
 Resource limits:
  Width: 107.374MP
  Height: 107.374MP
  List length: -1
  Area: 33.4532GP
  Memory: 15.5779GiB
  Map: 31.1558GiB
  Disk: unlimited
  File: 15000
  Thread: 8
  Throttle: 0
  Time: unlimited

我将感谢所有帮助我的人

0 个答案:

没有答案