Image ParallelRenderer::render (World& _world, Settings& _settings, Engine& _engine, SuperSampling& _super_sampling) { TaskDispatcher task_dispatcher(_settings); std::vector<std::future<Tiles>> futures(0); for (unsigned i = 0; i < _settings.max_thread_count; i++) { // TODO can this be done better? it must be possible futures.push_back(std::async(std::launch::async, [this, &task_dispatcher, &_world, &_settings, &_engine, &_super_sampling] () { return worker(task_dispatcher, _world, _settings, _engine, _super_sampling); })); } for (unsigned i = 0; i < futures.size(); i++) { futures[i].wait(); } Image final_image(_settings.area.size); for (unsigned i = 0; i < futures.size(); i++) { Tiles tiles = futures[i].get(); for (unsigned j = 0; j < tiles.size(); j++) { final_image.paste(tiles[j].task.start, tiles[j].image); } } return final_image; }
bool Frame::write_image( const char* file_path, const Image& image, const ImageAttributes& image_attributes) const { assert(file_path); Image final_image(image); transform_to_output_color_space(final_image); Stopwatch<DefaultWallclockTimer> stopwatch; stopwatch.start(); try { try { GenericImageFileWriter writer; writer.write(file_path, final_image, image_attributes); } catch (const ExceptionUnsupportedFileFormat&) { const string extension = lower_case(filesystem::path(file_path).extension()); RENDERER_LOG_ERROR( "file format '%s' not supported, writing the image in OpenEXR format " "(but keeping the filename unmodified).", extension.c_str()); EXRImageFileWriter writer; writer.write(file_path, final_image, image_attributes); } } catch (const ExceptionIOError&) { RENDERER_LOG_ERROR( "failed to write image file %s: i/o error.", file_path); return false; } catch (const Exception& e) { RENDERER_LOG_ERROR( "failed to write image file %s: %s.", file_path, e.what()); return false; } stopwatch.measure(); RENDERER_LOG_INFO( "wrote image file %s in %s.", file_path, pretty_time(stopwatch.get_seconds()).c_str()); return true; }
ImageRAII appendimages( IplImage * image1, IplImage * image2 ) { CvSize image1_size = cvGetSize( image1 ); CvSize image2_size = cvGetSize( image2 ); CvSize final_size = cvSize( image1_size.width + image2_size.width, std::max( image1_size.height, image2_size.height ) ); ImageRAII grayscale_image1( cvCreateImage( image1_size, image1->depth, 1 ) ); ImageRAII grayscale_image2( cvCreateImage( image2_size, image2->depth, 1 ) ); ImageRAII final_image( cvCreateImage( final_size, image1->depth, 1 ) ); // convert to grayscale cvCvtColor( image1, grayscale_image1.image, CV_BGR2GRAY ); cvCvtColor( image2, grayscale_image2.image, CV_BGR2GRAY ); int width_adjust = 0; // combine images side by side for( int i = 0; i < image1_size.width; i++ ) { for( int j = 0; j < image1_size.height; j++ ) { *( final_image.image->imageData + j * final_image.image->widthStep + final_image.image->nChannels * ( i + width_adjust ) ) = *( grayscale_image1.image->imageData + j * grayscale_image1.image->widthStep + grayscale_image1.image->nChannels * i ); } } width_adjust = image1_size.width; for( int i = 0; i < image2_size.width; i++ ) { for( int j = 0; j < image2_size.height; j++ ) { *( final_image.image->imageData + j * final_image.image->widthStep + final_image.image->nChannels * ( i + width_adjust ) ) = *( grayscale_image2.image->imageData + j * grayscale_image2.image->widthStep + grayscale_image2.image->nChannels * i ); } } return final_image; }
void RenderingManager::print_average_luminance() { Image final_image(m_project->get_frame()->image()); m_project->get_frame()->transform_to_output_color_space(final_image); const double average_luminance = compute_average_luminance(final_image); RENDERER_LOG_DEBUG( "final average luminance is %s.", pretty_scalar(average_luminance, 6).c_str()); }