Example: Progress Callbacks (C++ only)#
This example covers attaching a progress callback to the read/write operations of the LayeredFile allowing you to query the state of those operations asynchronously which is especially helpful when reading heavy files
Relevant documentation links:
/*
Example of writing a large PhotoshopFile asynchronously while using a callback to continuously query the state and progress of the file read operation
WARNING: This will write a rather large file to your disk ~1GB
This example does not have a python counterpart as we do not have an equivalent counterpart for the ProgressCallback& in python, if you would like
to suggest a change that would implement this please do so by creating a github pull request.
*/
#include "PhotoshopAPI.h"
#include <unordered_map>
#include <vector>
#include <random>
#include <ctime>
#include <iostream>
#include <future>
#include <functional>
#include <chrono>
#include <thread>
using namespace NAMESPACE_PSAPI;
// Simple wrapper function which simply executes the write asynchronously, this could also just be a lambda
template <typename T>
void AsyncWriteFile(LayeredFile<T>&& document, std::filesystem::path filePath, ProgressCallback& callback)
{
LayeredFile<T>::write(std::move(document), filePath, callback);
}
int main()
{
uint32_t width = 4096;
uint32_t height = 4096;
auto document = LayeredFile<bpp32_t>(Enum::ColorMode::RGB, width, height);
// Generate some random image data which will compress badly to emulate longer write times
std::mt19937 rng(static_cast<unsigned>(std::time(0)));
std::uniform_real_distribution<bpp32_t> dist(0.0, 1.0);
std::vector<bpp32_t> imgData(width * height);
for (auto& value : imgData)
{
value = dist(rng);
}
// Add the layer 5 times to make execution longer
for (int i = 0; i < 5; ++i)
{
std::unordered_map <Enum::ChannelID, std::vector<bpp32_t>> channelMap;
channelMap[Enum::ChannelID::Red] = imgData;
channelMap[Enum::ChannelID::Green] = imgData;
channelMap[Enum::ChannelID::Blue] = imgData;
ImageLayer<bpp32_t>::Params layerParams = {};
layerParams.name = "Layer_" + std::to_string(i);
layerParams.width = width;
layerParams.height = height;
auto layer = std::make_shared<ImageLayer<bpp32_t>>(std::move(channelMap), layerParams);
document.add_layer(layer);
}
// Launch the file read asynchronously while attaching a callback which we pass by reference
ProgressCallback callback{};
auto future = std::async(std::launch::async,
&AsyncWriteFile<bpp32_t>, std::move(document), "ProgressCallbackExample.psd", std::ref(callback));
// Simulate some kind of loop where we continuously query the state of the progress until done
while (true)
{
if (future.valid())
if (future.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
{
std::cout << "Writing of file " << callback.getProgress() * 100 << "% completed. Current task: " << callback.getTask() << std::endl;
break;
}
std::cout << "Writing of file " << callback.getProgress()*100 << "% completed. Current task: " << callback.getTask() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
std::cout << "Finished writing file: 'ProgressCallbackExample.psd'" << std::endl;
}