Skip to content

Commit

Permalink
Fixing aspect ratio of tracked objects, since the tracked object ofte…
Browse files Browse the repository at this point in the history
…n is of varying aspect ratios (since the parent clip and tracked object can change over time). Clips which are parented to tracked objects now respect the scale_type (i.e. best fit, stretch, etc...).
  • Loading branch information
jonoomph committed Mar 3, 2024
1 parent 8b47373 commit ffb63f5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 87 deletions.
122 changes: 38 additions & 84 deletions src/Clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,33 +504,6 @@ std::string Clip::get_file_extension(std::string path)
return path.substr(path.find_last_of(".") + 1);
}

// Reverse an audio buffer
void Clip::reverse_buffer(juce::AudioBuffer<float>* buffer)
{
int number_of_samples = buffer->getNumSamples();
int channels = buffer->getNumChannels();

// Reverse array (create new buffer to hold the reversed version)
auto *reversed = new juce::AudioBuffer<float>(channels, number_of_samples);
reversed->clear();

for (int channel = 0; channel < channels; channel++)
{
int n=0;
for (int s = number_of_samples - 1; s >= 0; s--, n++)
reversed->getWritePointer(channel)[n] = buffer->getWritePointer(channel)[s];
}

// Copy the samples back to the original array
buffer->clear();
// Loop through channels, and get audio samples
for (int channel = 0; channel < channels; channel++)
// Get the audio samples for this channel
buffer->addFrom(channel, 0, reversed->getReadPointer(channel), number_of_samples, 1.0f);

delete reversed;
}

// Adjust the audio and image of a time mapped frame
void Clip::apply_timemapping(std::shared_ptr<Frame> frame)
{
Expand Down Expand Up @@ -1315,8 +1288,7 @@ void Clip::apply_waveform(std::shared_ptr<Frame> frame, QSize timeline_size) {
std::shared_ptr<QImage> source_image = frame->GetImage();

// Debug output
ZmqLogger::Instance()->AppendDebugMethod(
"Clip::apply_waveform (Generate Waveform Image)",
ZmqLogger::Instance()->AppendDebugMethod("Clip::apply_waveform (Generate Waveform Image)",

Check warning on line 1291 in src/Clip.cpp

View check run for this annotation

Codecov / codecov/patch

src/Clip.cpp#L1291

Added line #L1291 was not covered by tests
"frame->number", frame->number,
"Waveform()", Waveform(),
"width", timeline_size.width(),
Expand All @@ -1333,6 +1305,27 @@ void Clip::apply_waveform(std::shared_ptr<Frame> frame, QSize timeline_size) {
frame->AddImage(source_image);
}

// Scale a source size to a target size (given a specific scale-type)
QSize Clip::scale_size(QSize source_size, ScaleType source_scale, int target_width, int target_height) {
switch (source_scale)
{
case (SCALE_FIT): {
source_size.scale(target_width, target_height, Qt::KeepAspectRatio);
break;
}
case (SCALE_STRETCH): {
source_size.scale(target_width, target_height, Qt::IgnoreAspectRatio);
break;

Check warning on line 1318 in src/Clip.cpp

View check run for this annotation

Codecov / codecov/patch

src/Clip.cpp#L1316-L1318

Added lines #L1316 - L1318 were not covered by tests
}
case (SCALE_CROP): {
source_size.scale(target_width, target_height, Qt::KeepAspectRatioByExpanding);;
break;

Check warning on line 1322 in src/Clip.cpp

View check run for this annotation

Codecov / codecov/patch

src/Clip.cpp#L1320-L1322

Added lines #L1320 - L1322 were not covered by tests
}
}

return source_size;
}

// Get QTransform from keyframes
QTransform Clip::get_transform(std::shared_ptr<Frame> frame, int width, int height)
{
Expand All @@ -1359,63 +1352,13 @@ QTransform Clip::get_transform(std::shared_ptr<Frame> frame, int width, int heig
}

// Debug output
ZmqLogger::Instance()->AppendDebugMethod(
"Clip::get_transform (Set Alpha & Opacity)",
ZmqLogger::Instance()->AppendDebugMethod("Clip::get_transform (Set Alpha & Opacity)",
"alpha_value", alpha_value,
"frame->number", frame->number);
}

/* RESIZE SOURCE IMAGE - based on scale type */
QSize source_size = source_image->size();

switch (scale)
{
case (SCALE_FIT): {
source_size.scale(width, height, Qt::KeepAspectRatio);

// Debug output
ZmqLogger::Instance()->AppendDebugMethod(
"Clip::get_transform (Scale: SCALE_FIT)",
"frame->number", frame->number,
"source_width", source_size.width(),
"source_height", source_size.height());
break;
}
case (SCALE_STRETCH): {
source_size.scale(width, height, Qt::IgnoreAspectRatio);

// Debug output
ZmqLogger::Instance()->AppendDebugMethod(
"Clip::get_transform (Scale: SCALE_STRETCH)",
"frame->number", frame->number,
"source_width", source_size.width(),
"source_height", source_size.height());
break;
}
case (SCALE_CROP): {
source_size.scale(width, height, Qt::KeepAspectRatioByExpanding);

// Debug output
ZmqLogger::Instance()->AppendDebugMethod(
"Clip::get_transform (Scale: SCALE_CROP)",
"frame->number", frame->number,
"source_width", source_size.width(),
"source_height", source_size.height());
break;
}
case (SCALE_NONE): {
// Image is already the original size (i.e. no scaling mode) relative
// to the preview window size (i.e. timeline / preview ratio). No further
// scaling is needed here.
// Debug output
ZmqLogger::Instance()->AppendDebugMethod(
"Clip::get_transform (Scale: SCALE_NONE)",
"frame->number", frame->number,
"source_width", source_size.width(),
"source_height", source_size.height());
break;
}
}
QSize source_size = scale_size(source_image->size(), scale, width, height);

// Initialize parent object's properties (Clip or Tracked Object)
float parentObject_location_x = 0.0;
Expand Down Expand Up @@ -1455,11 +1398,22 @@ QTransform Clip::get_transform(std::shared_ptr<Frame> frame, int width, int heig
// Access the parentTrackedObject's properties
std::map<std::string, float> trackedObjectProperties = parentTrackedObject->GetBoxValues(parent_frame_number);

// Get the Tracked Object's properties and correct them by the clip's reference system
// Get actual scaled parent size
QSize parent_size = scale_size(QSize(parentClip->info.width, parentClip->info.height),
parentClip->scale, width, height);

// Get actual scaled tracked object size
int trackedWidth = trackedObjectProperties["w"] * trackedObjectProperties["sx"] * parent_size.width() *
parentClip->scale_x.GetValue(parent_frame_number);
int trackedHeight = trackedObjectProperties["h"] * trackedObjectProperties["sy"] * parent_size.height() *
parentClip->scale_y.GetValue(parent_frame_number);

// Scale the clip source_size based on the actual tracked object size
source_size = scale_size(source_size, scale, trackedWidth, trackedHeight);

// Update parentObject's properties based on the tracked object's properties and parent clip's scale
parentObject_location_x = parentClip->location_x.GetValue(parent_frame_number) + ((trackedObjectProperties["cx"] - 0.5) * parentClip->scale_x.GetValue(parent_frame_number));
parentObject_location_y = parentClip->location_y.GetValue(parent_frame_number) + ((trackedObjectProperties["cy"] - 0.5) * parentClip->scale_y.GetValue(parent_frame_number));
parentObject_scale_x = trackedObjectProperties["w"] * trackedObjectProperties["sx"] * parentClip->scale_x.GetValue(parent_frame_number);
parentObject_scale_y = trackedObjectProperties["h"] * trackedObjectProperties["sy"] * parentClip->scale_y.GetValue(parent_frame_number);
parentObject_rotation = trackedObjectProperties["r"] + parentClip->rotation.GetValue(parent_frame_number);
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/Clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@ namespace openshot {
/// Sort effects by order
void sort_effects();

/// Reverse an audio buffer
void reverse_buffer(juce::AudioBuffer<float>* buffer);

/// Scale a source size to a target size (given a specific scale-type)
QSize scale_size(QSize source_size, ScaleType source_scale, int target_width, int target_height);

public:
openshot::GravityType gravity; ///< The gravity of a clip determines where it snaps to its parent
Expand Down

0 comments on commit ffb63f5

Please sign in to comment.