ImageMagick Magick ++ очень медленно пишет GIF - PullRequest
0 голосов
/ 20 сентября 2018

Я написал простое приложение на C ++, используя gdal и Magick ++.Программа берет tiff, разработанный из Gdal, и добавляет его к GIF-магии.Процесс очень медленный и использует около 800 МБ оперативной памяти (всего 24 кадра) ... и занимает 15 секунд. Я попытался оптимизировать входные файлы в соответствии с этим http://im.snibgo.com/spdsiz.htm, но процесс все еще медленный. Я работаю длячасть веб-службы, поэтому 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 (какой-либо более быстрый формат?)
  • чтение PNG с помощью .read
  • , аннотирование изображений с помощью отметки времени
  • добавление фонаи ZA над картой *
  • добавить рамку к вектору изображения
  • написать вектор

* я попытался выполнить эту операцию после сбора всех изображений,избегая делать это для каждого изображения, но я не мог этого сделать.

я пытался преобразовать фон в 2-х цветный png, а затем в miff-файл, а затем в кэш mpc +.PNG использует альфа и 1 цвет, я сделал тот же процесс

Какие самые быстрыеormats для ситуации?Мне также нужно, чтобы gif занимал как можно меньше (сейчас он занимает 5,4 МБ !!)

Как уже говорилось, операция должна быть очень быстрой, чтобы я мог также считать другие библиотеки более простыми ... просто исправил эти основные проблемыбудет прибегать к многопоточности (любой оптимальный метод?), но из моих тестов самая длинная фаза - это запись gif на диск (ramdisk выше)

Пример результата: https://photos.app.goo.gl/6YVkqSMuoXwMYuE57

Google фотоальбом: https://photos.app.goo.gl/QDNCAK4i9PCGQW3VA

РЕДАКТИРОВАТЬ Спасибо за быстрые комментарии

Я опоздал на Arch Linux, но финальная программа запустит веб-сервер неэтот мощный Debian 9.5, 4 виртуальных ядра и 8 ГБ оперативной памяти (при необходимости я могу попросить об улучшении, но не слишком много

должен управлять как минимум 24 кадрами, но я мог бы даже получить 700 ...изначально изображения занимают 130 КБ, но добавление цветов прибытия к 400 КБ. Это перед добавлением фона и разделением зон (см. изображения в альбоме Google)

я компилирую с G ++ 8.2.1 этоcmake file

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

Iбуду благодарен всем, кто мне поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...