Я написал простое приложение на 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буду благодарен всем, кто мне поможет