I wrote a simple c++ app using gdal and Magick++
The program takes the tiff elaborated from Gdal and add it to a Magick gif
The process is really slow and use around 800 MB of ram... and takes 15 seconds
I tried to optimize the input files according to this http://im.snibgo.com/spdsiz.htm but the process still slow
Im working for a part of a web service, so 15 second is really too much
Code: Select all
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 disk
//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;
}
get the tifs, do some work with gdal and write the files as png (any faster format?)
read the PNGs with .read
annotate the images with the timestamp
add the background and the ZA over the map *
add the frame to the image vector
write the vector
*i tryed to do this operation after collecting all images, avoiding doing it for each image, but I could not do it.
i tried to convert the background to a 2 colors png, and then to a miff file, and then to a mpc+cache one
the za.png uses alpha and 1 color, i done the same process
as said the operation must be very fast so I can also consider other libraries simpler ... just fixed these basic problems will resort to multithread but from my tests the longest phase is the one that writes the gif on the disk (ramdisk above)
sample of the result
https://photos.app.goo.gl/6YVkqSMuoXwMYuE57
I will be grateful to anyone who helps me