void SnapshotAnimated::processFrames() { uint32_t width = SnapshotAnimated::snapshotAnimatedFrameVector[0].width(); uint32_t height = SnapshotAnimated::snapshotAnimatedFrameVector[0].height(); // Create the GIF from the temporary files // Write out the header and beginning of the GIF file GifBegin( &(SnapshotAnimated::snapshotAnimatedGifWriter), qPrintable(SnapshotAnimated::snapshotAnimatedPath), width, height, 1); // "1" means "yes there is a delay" with this GifCreator library. for (int itr = 0; itr < SnapshotAnimated::snapshotAnimatedFrameVector.size(); itr++) { // Write each frame to the GIF GifWriteFrame(&(SnapshotAnimated::snapshotAnimatedGifWriter), (uint8_t*)SnapshotAnimated::snapshotAnimatedFrameVector[itr].convertToFormat(QImage::Format_RGBA8888).bits(), width, height, SnapshotAnimated::snapshotAnimatedFrameDelayVector[itr]); } // Write out the end of the GIF GifEnd(&(SnapshotAnimated::snapshotAnimatedGifWriter)); // Clear out the frame and frame delay vectors. // Also release the memory not required to store the items. SnapshotAnimated::snapshotAnimatedFrameVector.clear(); SnapshotAnimated::snapshotAnimatedFrameVector.squeeze(); SnapshotAnimated::snapshotAnimatedFrameDelayVector.clear(); SnapshotAnimated::snapshotAnimatedFrameDelayVector.squeeze(); // Let the dependency manager know that the snapshots have been taken. emit SnapshotAnimated::snapshotAnimatedDM->snapshotTaken(SnapshotAnimated::snapshotStillPath, SnapshotAnimated::snapshotAnimatedPath, false); }
bool gif_start_recording(const char *filename, unsigned int frameskip_) { std::lock_guard<std::mutex> lock(gif_mutex); if (GifBegin(&writer, filename, 320, 240, 1)) { recording = true; frame = 0; frameskip = frameskip_; gifTime = 0; } return recording; }
bool GIFOutput::start_subimage() { // Check for things this format doesn't support if (m_spec.width < 1 || m_spec.height < 1) { error("Image resolution must be at least 1x1, you asked for %d x %d", m_spec.width, m_spec.height); return false; } if (m_spec.depth < 1) m_spec.depth = 1; if (m_spec.depth > 1) { error("%s does not support volume images (depth > 1)", format_name()); return false; } if (m_spec.nchannels != 3 && m_spec.nchannels != 4) { error("%s does not support %d-channel images", format_name(), m_spec.nchannels); return false; } m_spec.set_format(TypeDesc::UINT8); // GIF is only 8 bit if (m_subimage == 0) { bool ok = GifBegin(&m_gifwriter, m_filename.c_str(), m_spec.width, m_spec.height, m_delay, 8 /*bit depth*/, true /*dither*/); if (!ok) { errorf("Could not open \"%s\"", m_filename); return false; } } m_canvas.clear(); m_canvas.resize(size_t(m_spec.image_pixels() * 4), 255); m_pending_write = true; return true; }
void GifSaver::save() { std::vector< uint8_t* > bufferVector; GifWriter gifWriter; GifBegin( &gifWriter, _outputFilePath.toStdString().c_str(), _inputAnimatedGif[ 0 ]->getWidth() * _scaleFactor, _inputAnimatedGif[ 0 ]->getHeight() * _scaleFactor, 10 ); int i = 0; for( const auto& frame : _inputAnimatedGif ) { _filter->setNewInputImage( frame ); _filter->apply(); Image* outputFrame = new Image( new QImage( *( _filter->getOutputImage()->getQImage() ) ) ); const int rgbaSize = 4; uint8_t* outputFrameBuffer = new uint8_t[ outputFrame->getWidth() * outputFrame->getHeight() * rgbaSize ]; outputFrame->getBufferRGBA8( outputFrameBuffer ); bufferVector.push_back( outputFrameBuffer ); GifWriteFrame( &gifWriter, outputFrameBuffer, outputFrame->getWidth(), outputFrame->getHeight(), 10 ); delete outputFrame; delete[] outputFrameBuffer; emit setProgress( ( float ) i++ * 100 / _inputAnimatedGif.size() ); } GifEnd( &gifWriter ); }
bool gif_single_frame(const char *filename) { GifWriter frameWriter; return GifBegin(&frameWriter, filename, 320, 240, 0) && gif_write_frame(&frameWriter, 0) && GifEnd(&frameWriter); }