@@ -440,21 +440,18 @@ std::shared_ptr<Frame> Clip::GetFrame(std::shared_ptr<openshot::Frame> backgroun
440440 // Apply waveform image (if any)
441441 apply_waveform (frame, background_frame);
442442
443- // Apply local effects to the frame (if any)
444- apply_effects (frame);
443+ // Apply effects BEFORE applying keyframes (if any local or global effects are used )
444+ apply_effects (frame, background_frame, options, true );
445445
446- // Apply global timeline effects (i.e. transitions & masks... if any)
447- if (timeline != NULL && options != NULL ) {
448- if (options->is_top_clip ) {
449- // Apply global timeline effects (only to top clip... if overlapping, pass in timeline frame number)
450- Timeline* timeline_instance = static_cast <Timeline*>(timeline);
451- frame = timeline_instance->apply_effects (frame, background_frame->number , Layer ());
452- }
453- }
454-
455- // Apply keyframe / transforms
446+ // Apply keyframe / transforms to current clip image
456447 apply_keyframes (frame, background_frame);
457448
449+ // Apply effects AFTER applying keyframes (if any local or global effects are used)
450+ apply_effects (frame, background_frame, options, false );
451+
452+ // Apply background canvas (i.e. flatten this image onto previous layer image)
453+ apply_background (frame, background_frame);
454+
458455 // Add final frame to cache
459456 final_cache.Add (frame);
460457
@@ -1202,16 +1199,41 @@ void Clip::RemoveEffect(EffectBase* effect)
12021199 final_cache.Clear ();
12031200}
12041201
1202+ // Apply background image to the current clip image (i.e. flatten this image onto previous layer)
1203+ void Clip::apply_background (std::shared_ptr<openshot::Frame> frame, std::shared_ptr<openshot::Frame> background_frame) {
1204+ // Add background canvas
1205+ std::shared_ptr<QImage> background_canvas = background_frame->GetImage ();
1206+ QPainter painter (background_canvas.get ());
1207+ painter.setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing, true );
1208+
1209+ // Composite a new layer onto the image
1210+ painter.setCompositionMode (QPainter::CompositionMode_SourceOver);
1211+ painter.drawImage (0 , 0 , *frame->GetImage ());
1212+ painter.end ();
1213+
1214+ // Add new QImage to frame
1215+ frame->AddImage (background_canvas);
1216+ }
1217+
12051218// Apply effects to the source frame (if any)
1206- void Clip::apply_effects (std::shared_ptr<Frame> frame)
1219+ void Clip::apply_effects (std::shared_ptr<Frame> frame, std::shared_ptr<Frame> background_frame, TimelineInfoStruct* options, bool before_keyframes )
12071220{
1208- // Find Effects at this position and layer
12091221 for (auto effect : effects)
12101222 {
12111223 // Apply the effect to this frame
1212- frame = effect->GetFrame (frame, frame->number );
1224+ if (effect->info .apply_before_clip && before_keyframes) {
1225+ effect->GetFrame (frame, frame->number );
1226+ } else if (!effect->info .apply_before_clip && !before_keyframes) {
1227+ effect->GetFrame (frame, frame->number );
1228+ }
1229+ }
12131230
1214- } // end effect loop
1231+ if (timeline != NULL && options != NULL ) {
1232+ // Apply global timeline effects (i.e. transitions & masks... if any)
1233+ Timeline* timeline_instance = static_cast <Timeline*>(timeline);
1234+ options->is_before_clip_keyframes = before_keyframes;
1235+ timeline_instance->apply_effects (frame, background_frame->number , Layer (), options);
1236+ }
12151237}
12161238
12171239// Compare 2 floating point numbers for equality
@@ -1228,20 +1250,16 @@ void Clip::apply_keyframes(std::shared_ptr<Frame> frame, std::shared_ptr<Frame>
12281250 return ;
12291251 }
12301252
1231- // Get image from clip
1253+ // Get image from clip, and create transparent background image
12321254 std::shared_ptr<QImage> source_image = frame->GetImage ();
1233- std::shared_ptr<QImage> background_canvas = background_frame->GetImage ();
1255+ std::shared_ptr<QImage> background_canvas = std::make_shared<QImage>(background_frame->GetImage ()->width (),
1256+ background_frame->GetImage ()->height (),
1257+ QImage::Format_RGBA8888_Premultiplied);
1258+ background_canvas->fill (QColor (Qt::transparent));
12341259
12351260 // Get transform from clip's keyframes
12361261 QTransform transform = get_transform (frame, background_canvas->width (), background_canvas->height ());
12371262
1238- // Debug output
1239- ZmqLogger::Instance ()->AppendDebugMethod (
1240- " Clip::ApplyKeyframes (Transform: Composite Image Layer: Prepare)" ,
1241- " frame->number" , frame->number ,
1242- " background_canvas->width()" , background_canvas->width (),
1243- " background_canvas->height()" , background_canvas->height ());
1244-
12451263 // Load timeline's new frame image into a QPainter
12461264 QPainter painter (background_canvas.get ());
12471265 painter.setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing, true );
0 commit comments