OpenShot Library | libopenshot  0.7.0
ColorGrade.cpp
Go to the documentation of this file.
1 
9 // Copyright (c) 2008-2026 OpenShot Studios, LLC
10 //
11 // SPDX-License-Identifier: LGPL-3.0-or-later
12 
13 #include "ColorGrade.h"
14 #include "Exceptions.h"
15 
16 #include <algorithm>
17 #include <array>
18 #include <cmath>
19 #include <sstream>
20 
21 using namespace openshot;
22 
23 namespace {
24 constexpr float kInv255 = 1.0f / 255.0f;
25 
26 struct WheelBiasParams {
27  float red_delta;
28  float green_delta;
29  float blue_delta;
30 };
31 
32 static inline float clamp01(float value) {
33  return std::max(0.0f, std::min(1.0f, value));
34 }
35 
36 static inline int clampByte(float value) {
37  if (value <= 0.0f)
38  return 0;
39  if (value >= 255.0f)
40  return 255;
41  return static_cast<int>(value + 0.5f);
42 }
43 
44 static inline float smooth_midtones(float luma) {
45  const float centered = std::abs(luma - 0.5f) * 2.0f;
46  return clamp01(1.0f - centered * centered);
47 }
48 
49 static std::string color_to_hex(const QColor& color) {
50  return color.name(QColor::HexRgb).toStdString();
51 }
52 
53 static std::array<float, 256> build_curve_lut(const AnimatedCurve& curve, int64_t frame_number) {
54  std::array<float, 256> lut{};
55  if (curve.enabled.GetValue(frame_number) < 0.5) {
56  for (size_t i = 0; i < lut.size(); ++i)
57  lut[i] = static_cast<float>(i) * kInv255;
58  return lut;
59  }
60 
61  const Keyframe sampled_curve = curve.BuildCurve(frame_number, 255.0);
62  for (size_t i = 0; i < lut.size(); ++i) {
63  lut[i] = clamp01(static_cast<float>(sampled_curve.GetValue(static_cast<int64_t>(i))));
64  }
65  return lut;
66 }
67 
68 static float sample_curve_lut(const std::array<float, 256>& lut, float value) {
69  return lut[static_cast<int>(value * 255.0f + 0.5f)];
70 }
71 
72 static WheelBiasParams build_wheel_bias(const ColorGradeWheelEntry& wheel, int64_t frame_number) {
73  const QColor color = wheel.GetColor(frame_number);
74  const float cr = color.redF();
75  const float cg = color.greenF();
76  const float cb = color.blueF();
77  const float avg = (cr + cg + cb) / 3.0f;
78  const float amount = wheel.GetAmount(frame_number);
79  const float luma = wheel.GetLuma(frame_number);
80  return {
81  ((cr - avg) * amount) + luma,
82  ((cg - avg) * amount) + luma,
83  ((cb - avg) * amount) + luma,
84  };
85 }
86 }
87 
89  : color(QColor(Qt::white)), amount(0.0f), luma(0.0f) {}
90 
91 Json::Value ColorGradeWheelEntry::JsonValue() const {
92  Json::Value root(Json::objectValue);
93  root["color"] = color_to_hex(QColor(
94  color.red.GetInt(1),
95  color.green.GetInt(1),
96  color.blue.GetInt(1),
97  color.alpha.GetInt(1)));
98  root["color_keyframes"] = color.JsonValue();
99  root["amount"] = amount.GetValue(1);
100  root["amount_keyframes"] = amount.JsonValue();
101  root["luma"] = luma.GetValue(1);
102  root["luma_keyframes"] = luma.JsonValue();
103  return root;
104 }
105 
106 void ColorGradeWheelEntry::SetJsonValue(const Json::Value& root) {
107  if (!root["color_keyframes"].isNull()) {
108  color.SetJsonValue(root["color_keyframes"]);
109  } else if (!root["color"].isNull()) {
110  const QColor parsed(QString::fromStdString(root["color"].asString()));
111  if (parsed.isValid())
112  color = Color(parsed);
113  }
114  if (!root["amount_keyframes"].isNull())
115  amount.SetJsonValue(root["amount_keyframes"]);
116  else if (!root["amount"].isNull())
117  amount = Keyframe(std::max(-1.0f, std::min(1.0f, root["amount"].asFloat())));
118  if (!root["luma_keyframes"].isNull())
119  luma.SetJsonValue(root["luma_keyframes"]);
120  else if (!root["luma"].isNull())
121  luma = Keyframe(std::max(-1.0f, std::min(1.0f, root["luma"].asFloat())));
122 }
123 
124 QColor ColorGradeWheelEntry::GetColor(int64_t frame_number) const {
125  return QColor(
126  color.red.GetInt(frame_number),
127  color.green.GetInt(frame_number),
128  color.blue.GetInt(frame_number),
129  color.alpha.GetInt(frame_number));
130 }
131 
132 float ColorGradeWheelEntry::GetAmount(int64_t frame_number) const {
133  return std::max(-1.0f, std::min(1.0f, static_cast<float>(amount.GetValue(frame_number))));
134 }
135 
136 float ColorGradeWheelEntry::GetLuma(int64_t frame_number) const {
137  return std::max(-1.0f, std::min(1.0f, static_cast<float>(luma.GetValue(frame_number))));
138 }
139 
141  : enabled(1.0) {}
142 
143 Json::Value ColorGradeWheelsData::JsonValue() const {
144  Json::Value root(Json::objectValue);
145  root["enabled"] = enabled.GetValue(1) >= 0.5;
146  root["enabled_keyframes"] = enabled.JsonValue();
147  root["global"] = global.JsonValue();
148  root["shadows"] = shadows.JsonValue();
149  root["midtones"] = midtones.JsonValue();
150  root["highlights"] = highlights.JsonValue();
151  return root;
152 }
153 
154 void ColorGradeWheelsData::SetJsonValue(const Json::Value& root) {
155  if (root["enabled"].isBool())
156  enabled = Keyframe(root["enabled"].asBool() ? 1.0 : 0.0);
157  else if (!root["enabled_keyframes"].isNull())
158  enabled.SetJsonValue(root["enabled_keyframes"]);
159  if (!root["global"].isNull())
160  global.SetJsonValue(root["global"]);
161  if (!root["shadows"].isNull())
162  shadows.SetJsonValue(root["shadows"]);
163  if (!root["midtones"].isNull())
164  midtones.SetJsonValue(root["midtones"]);
165  if (!root["highlights"].isNull())
166  highlights.SetJsonValue(root["highlights"]);
167 }
168 
169 std::string ColorGradeWheelsData::Summary(int64_t frame_number) const {
170  return IsEnabled(frame_number) ? "Global / Shadows / Midtones / Highlights"
171  : "Disabled";
172 }
173 
174 bool ColorGradeWheelsData::IsEnabled(int64_t frame_number) const {
175  return enabled.GetValue(frame_number) >= 0.5;
176 }
177 
179  : temperature(0.0),
180  tint(0.0),
181  exposure(0.0),
182  contrast(0.0),
183  highlights(0.0),
184  shadows(0.0),
185  saturation(1.0),
186  vibrance(0.0),
187  mix(1.0),
188  lut_intensity(1.0),
189  lut_path(""),
190  lut_dirty(true)
191 {
192  init_effect_details();
193 }
194 
195 void ColorGrade::init_effect_details() {
196  InitEffectInfo();
197  info.class_name = "ColorGrade";
198  info.name = "Color Grade";
199  info.description = "Unified color grading effect with curves, wheels and LUT support.";
200  info.has_audio = false;
201  info.has_video = true;
202 }
203 
204 float ColorGrade::Clamp01(float value) {
205  return clamp01(value);
206 }
207 
208 void ColorGrade::sync_lut_effect() {
209  if (!lut_dirty)
210  return;
211 
212  Json::Value payload(Json::objectValue);
213  payload["lut_path"] = lut_path;
214  payload["intensity"] = lut_intensity.JsonValue();
215  payload["intensity_r"] = Keyframe(1.0).JsonValue();
216  payload["intensity_g"] = Keyframe(1.0).JsonValue();
217  payload["intensity_b"] = Keyframe(1.0).JsonValue();
218  lut_effect.SetJsonValue(payload);
219  lut_dirty = false;
220 }
221 
222 std::shared_ptr<openshot::Frame> ColorGrade::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number) {
223  std::shared_ptr<QImage> frame_image = frame->GetImage();
224  if (!frame_image)
225  return frame;
226 
227  const float temperature_value = std::max(-1.0f, std::min(1.0f, static_cast<float>(temperature.GetValue(frame_number))));
228  const float tint_value = std::max(-1.0f, std::min(1.0f, static_cast<float>(tint.GetValue(frame_number))));
229  const float exposure_value = std::max(-4.0f, std::min(4.0f, static_cast<float>(exposure.GetValue(frame_number))));
230  const float contrast_value = std::max(-1.0f, std::min(2.0f, static_cast<float>(contrast.GetValue(frame_number))));
231  const float highlights_value = std::max(-1.0f, std::min(1.0f, static_cast<float>(highlights.GetValue(frame_number))));
232  const float shadows_value = std::max(-1.0f, std::min(1.0f, static_cast<float>(shadows.GetValue(frame_number))));
233  const float saturation_value = std::max(0.0f, std::min(4.0f, static_cast<float>(saturation.GetValue(frame_number))));
234  const float vibrance_value = std::max(-1.0f, std::min(1.0f, static_cast<float>(vibrance.GetValue(frame_number))));
235  const float mix_value = std::max(0.0f, std::min(1.0f, static_cast<float>(mix.GetValue(frame_number))));
236  const float inverse_mix = 1.0f - mix_value;
237  const bool wheels_enabled = wheels.IsEnabled(frame_number);
238  if (temperature_value == 0.0f && tint_value == 0.0f &&
239  exposure_value == 0.0f && contrast_value == 0.0f &&
240  highlights_value == 0.0f && shadows_value == 0.0f &&
241  saturation_value == 1.0f && vibrance_value == 0.0f &&
242  mix_value == 1.0f && !wheels_enabled &&
243  curve_all.enabled.GetValue(frame_number) < 0.5 &&
244  curve_red.enabled.GetValue(frame_number) < 0.5 &&
245  curve_green.enabled.GetValue(frame_number) < 0.5 &&
246  curve_blue.enabled.GetValue(frame_number) < 0.5) {
247  if (!lut_path.empty() && lut_intensity.GetValue(frame_number) > 0.0) {
248  sync_lut_effect();
249  return lut_effect.GetFrame(frame, frame_number);
250  }
251  return frame;
252  }
253  const float exposure_gain = std::pow(2.0f, exposure_value);
254  const float contrast_factor = std::max(0.0f, 1.0f + contrast_value);
255  const std::array<float, 256> curve_all_lut = build_curve_lut(curve_all, frame_number);
256  const std::array<float, 256> curve_red_lut = build_curve_lut(curve_red, frame_number);
257  const std::array<float, 256> curve_green_lut = build_curve_lut(curve_green, frame_number);
258  const std::array<float, 256> curve_blue_lut = build_curve_lut(curve_blue, frame_number);
259  const WheelBiasParams global_wheel = wheels_enabled ? build_wheel_bias(wheels.global, frame_number) : WheelBiasParams{0.0f, 0.0f, 0.0f};
260  const WheelBiasParams shadows_wheel = wheels_enabled ? build_wheel_bias(wheels.shadows, frame_number) : WheelBiasParams{0.0f, 0.0f, 0.0f};
261  const WheelBiasParams midtones_wheel = wheels_enabled ? build_wheel_bias(wheels.midtones, frame_number) : WheelBiasParams{0.0f, 0.0f, 0.0f};
262  const WheelBiasParams highlights_wheel = wheels_enabled ? build_wheel_bias(wheels.highlights, frame_number) : WheelBiasParams{0.0f, 0.0f, 0.0f};
263 
264  static const std::array<float, 256> inv_alpha = [] {
265  std::array<float, 256> lut{};
266  lut[0] = 0.0f;
267  for (int i = 1; i < 256; ++i)
268  lut[i] = 255.0f / static_cast<float>(i);
269  return lut;
270  }();
271 
272  const auto apply_wheel_bias = [](const WheelBiasParams& wheel, float weight, float& r, float& g, float& b) {
273  if (std::abs(weight) <= 0.00001f)
274  return;
275  r += wheel.red_delta * weight;
276  g += wheel.green_delta * weight;
277  b += wheel.blue_delta * weight;
278  };
279 
280  unsigned char* pixels = reinterpret_cast<unsigned char*>(frame_image->bits());
281  const int pixel_count = frame_image->width() * frame_image->height();
282 
283  #pragma omp parallel for if(pixel_count >= 16384) schedule(static)
284  for (int pixel = 0; pixel < pixel_count; ++pixel) {
285  const int idx = pixel * 4;
286  const int A = pixels[idx + 3];
287  if (A <= 0)
288  continue;
289 
290  const float alpha_percent = static_cast<float>(A) * kInv255;
291  float R = 0.0f;
292  float G = 0.0f;
293  float B = 0.0f;
294 
295  if (A == 255) {
296  R = pixels[idx + 0] * kInv255;
297  G = pixels[idx + 1] * kInv255;
298  B = pixels[idx + 2] * kInv255;
299  } else {
300  const float inv_alpha_percent = inv_alpha[A];
301  R = (pixels[idx + 0] * inv_alpha_percent) * kInv255;
302  G = (pixels[idx + 1] * inv_alpha_percent) * kInv255;
303  B = (pixels[idx + 2] * inv_alpha_percent) * kInv255;
304  }
305 
306  const float original_r = R;
307  const float original_g = G;
308  const float original_b = B;
309 
310  // White-balance style controls.
311  R = Clamp01(R + (temperature_value * 0.125f));
312  B = Clamp01(B - (temperature_value * 0.125f));
313  G = Clamp01(G - (tint_value * 0.1f));
314  R = Clamp01(R + (tint_value * 0.05f));
315  B = Clamp01(B + (tint_value * 0.05f));
316 
317  // Exposure and contrast.
318  R = Clamp01(R * exposure_gain);
319  G = Clamp01(G * exposure_gain);
320  B = Clamp01(B * exposure_gain);
321 
322  R = Clamp01(((R - 0.5f) * contrast_factor) + 0.5f);
323  G = Clamp01(((G - 0.5f) * contrast_factor) + 0.5f);
324  B = Clamp01(((B - 0.5f) * contrast_factor) + 0.5f);
325 
326  float luma = (0.299f * R) + (0.587f * G) + (0.114f * B);
327  const float shadow_weight = (1.0f - luma) * (1.0f - luma);
328  const float highlight_weight = luma * luma;
329 
330  // Shadows/highlights recovery.
331  const float shadow_adjust = shadows_value * shadow_weight * 0.35f;
332  const float highlight_adjust = highlights_value * highlight_weight * 0.35f;
333  R = Clamp01(R + shadow_adjust + highlight_adjust);
334  G = Clamp01(G + shadow_adjust + highlight_adjust);
335  B = Clamp01(B + shadow_adjust + highlight_adjust);
336 
337  // Tonal wheels.
338  luma = (0.299f * R) + (0.587f * G) + (0.114f * B);
339  float wheel_r = R;
340  float wheel_g = G;
341  float wheel_b = B;
342  if (wheels_enabled) {
343  apply_wheel_bias(global_wheel, 1.0f, wheel_r, wheel_g, wheel_b);
344  apply_wheel_bias(shadows_wheel, (1.0f - luma) * (1.0f - luma), wheel_r, wheel_g, wheel_b);
345  apply_wheel_bias(midtones_wheel, smooth_midtones(luma), wheel_r, wheel_g, wheel_b);
346  apply_wheel_bias(highlights_wheel, luma * luma, wheel_r, wheel_g, wheel_b);
347  }
348  R = Clamp01(wheel_r);
349  G = Clamp01(wheel_g);
350  B = Clamp01(wheel_b);
351 
352  // Saturation and vibrance.
353  luma = (0.299f * R) + (0.587f * G) + (0.114f * B);
354  const float max_channel = std::max(R, std::max(G, B));
355  const float min_channel = std::min(R, std::min(G, B));
356  const float colorfulness = max_channel - min_channel;
357  const float vibrance_factor = 1.0f + (vibrance_value * (1.0f - colorfulness));
358  const float sat_factor = saturation_value * std::max(0.0f, vibrance_factor);
359  R = Clamp01(luma + ((R - luma) * sat_factor));
360  G = Clamp01(luma + ((G - luma) * sat_factor));
361  B = Clamp01(luma + ((B - luma) * sat_factor));
362 
363  // Curves.
364  R = sample_curve_lut(curve_all_lut, R);
365  G = sample_curve_lut(curve_all_lut, G);
366  B = sample_curve_lut(curve_all_lut, B);
367  R = sample_curve_lut(curve_red_lut, R);
368  G = sample_curve_lut(curve_green_lut, G);
369  B = sample_curve_lut(curve_blue_lut, B);
370 
371  // Mix original and graded values.
372  R = Clamp01((original_r * inverse_mix) + (R * mix_value));
373  G = Clamp01((original_g * inverse_mix) + (G * mix_value));
374  B = Clamp01((original_b * inverse_mix) + (B * mix_value));
375 
376  if (A == 255) {
377  pixels[idx + 0] = static_cast<unsigned char>(clampByte(R * 255.0f));
378  pixels[idx + 1] = static_cast<unsigned char>(clampByte(G * 255.0f));
379  pixels[idx + 2] = static_cast<unsigned char>(clampByte(B * 255.0f));
380  } else {
381  pixels[idx + 0] = static_cast<unsigned char>(clampByte(R * 255.0f * alpha_percent));
382  pixels[idx + 1] = static_cast<unsigned char>(clampByte(G * 255.0f * alpha_percent));
383  pixels[idx + 2] = static_cast<unsigned char>(clampByte(B * 255.0f * alpha_percent));
384  }
385  }
386 
387  if (!lut_path.empty() && lut_intensity.GetValue(frame_number) > 0.0) {
388  sync_lut_effect();
389  frame = lut_effect.GetFrame(frame, frame_number);
390  }
391 
392  return frame;
393 }
394 
395 std::string ColorGrade::Json() const {
396  return JsonValue().toStyledString();
397 }
398 
399 Json::Value ColorGrade::JsonValue() const {
400  Json::Value root = EffectBase::JsonValue();
401  root["type"] = info.class_name;
402  root["temperature"] = temperature.JsonValue();
403  root["tint"] = tint.JsonValue();
404  root["exposure"] = exposure.JsonValue();
405  root["contrast"] = contrast.JsonValue();
406  root["highlights"] = highlights.JsonValue();
407  root["shadows"] = shadows.JsonValue();
408  root["saturation"] = saturation.JsonValue();
409  root["vibrance"] = vibrance.JsonValue();
410  root["mix"] = mix.JsonValue();
411  root["wheels"] = wheels.JsonValue();
412  root["curve_all"] = curve_all.JsonValue();
413  root["curve_red"] = curve_red.JsonValue();
414  root["curve_green"] = curve_green.JsonValue();
415  root["curve_blue"] = curve_blue.JsonValue();
416  root["lut_path"] = lut_path;
417  root["lut_intensity"] = lut_intensity.JsonValue();
418  return root;
419 }
420 
421 void ColorGrade::SetJson(const std::string value) {
422  try {
423  const Json::Value root = openshot::stringToJson(value);
424  SetJsonValue(root);
425  } catch (...) {
426  throw InvalidJSON("Invalid JSON for ColorGrade effect");
427  }
428 }
429 
430 void ColorGrade::SetJsonValue(const Json::Value root) {
432 
433  if (!root["temperature"].isNull())
434  temperature.SetJsonValue(root["temperature"]);
435  if (!root["tint"].isNull())
436  tint.SetJsonValue(root["tint"]);
437  if (!root["exposure"].isNull())
438  exposure.SetJsonValue(root["exposure"]);
439  if (!root["contrast"].isNull())
440  contrast.SetJsonValue(root["contrast"]);
441  if (!root["highlights"].isNull())
442  highlights.SetJsonValue(root["highlights"]);
443  if (!root["shadows"].isNull())
444  shadows.SetJsonValue(root["shadows"]);
445  if (!root["saturation"].isNull())
446  saturation.SetJsonValue(root["saturation"]);
447  if (!root["vibrance"].isNull())
448  vibrance.SetJsonValue(root["vibrance"]);
449  if (!root["mix"].isNull())
450  mix.SetJsonValue(root["mix"]);
451  if (!root["wheels"].isNull())
452  wheels.SetJsonValue(root["wheels"]);
453  if (!root["curve_all"].isNull())
454  curve_all.SetJsonValue(root["curve_all"]);
455  if (!root["curve_red"].isNull())
456  curve_red.SetJsonValue(root["curve_red"]);
457  if (!root["curve_green"].isNull())
458  curve_green.SetJsonValue(root["curve_green"]);
459  if (!root["curve_blue"].isNull())
460  curve_blue.SetJsonValue(root["curve_blue"]);
461  if (!root["lut_path"].isNull()) {
462  lut_path = root["lut_path"].asString();
463  lut_dirty = true;
464  }
465  if (!root["lut_intensity"].isNull()) {
466  lut_intensity.SetJsonValue(root["lut_intensity"]);
467  lut_dirty = true;
468  }
469 }
470 
471 std::string ColorGrade::PropertiesJSON(int64_t requested_frame) const {
472  Json::Value root = BasePropertiesJSON(requested_frame);
473 
474  root["temperature"] = add_property_json("Temperature", temperature.GetValue(requested_frame), "float", "", &temperature, -1.0, 1.0, false, requested_frame);
475  root["tint"] = add_property_json("Tint", tint.GetValue(requested_frame), "float", "", &tint, -1.0, 1.0, false, requested_frame);
476  root["exposure"] = add_property_json("Exposure", exposure.GetValue(requested_frame), "float", "", &exposure, -2.0, 2.0, false, requested_frame);
477  root["contrast"] = add_property_json("Contrast", contrast.GetValue(requested_frame), "float", "", &contrast, -1.0, 1.0, false, requested_frame);
478  root["highlights"] = add_property_json("Highlights", highlights.GetValue(requested_frame), "float", "", &highlights, -1.0, 1.0, false, requested_frame);
479  root["shadows"] = add_property_json("Shadows", shadows.GetValue(requested_frame), "float", "", &shadows, -1.0, 1.0, false, requested_frame);
480  root["saturation"] = add_property_json("Saturation", saturation.GetValue(requested_frame), "float", "", &saturation, 0.0, 4.0, false, requested_frame);
481  root["vibrance"] = add_property_json("Vibrance", vibrance.GetValue(requested_frame), "float", "", &vibrance, -1.0, 1.0, false, requested_frame);
482  root["mix"] = add_property_json("Mix", mix.GetValue(requested_frame), "float", "", &mix, 0.0, 1.0, false, requested_frame);
483 
484  root["wheels"] = add_property_json("Color Wheels", 0.0, "colorgrade_wheels", wheels.Summary(requested_frame), NULL, 0.0, 1.0, false, requested_frame);
485  root["wheels"]["wheels"] = wheels.JsonValue();
486  root["wheels"]["summary"] = wheels.Summary(requested_frame);
487 
488  root["curve_all"] = add_property_json("Curve: All", 0.0, "colorgrade_curve", curve_all.Summary(requested_frame), NULL, 0.0, 1.0, false, requested_frame);
489  root["curve_all"]["curve"] = curve_all.JsonValue();
490  root["curve_all"]["channel"] = "all";
491  root["curve_all"]["summary"] = curve_all.Summary(requested_frame);
492 
493  root["curve_red"] = add_property_json("Curve: Red", 0.0, "colorgrade_curve", curve_red.Summary(requested_frame), NULL, 0.0, 1.0, false, requested_frame);
494  root["curve_red"]["curve"] = curve_red.JsonValue();
495  root["curve_red"]["channel"] = "red";
496  root["curve_red"]["summary"] = curve_red.Summary(requested_frame);
497 
498  root["curve_green"] = add_property_json("Curve: Green", 0.0, "colorgrade_curve", curve_green.Summary(requested_frame), NULL, 0.0, 1.0, false, requested_frame);
499  root["curve_green"]["curve"] = curve_green.JsonValue();
500  root["curve_green"]["channel"] = "green";
501  root["curve_green"]["summary"] = curve_green.Summary(requested_frame);
502 
503  root["curve_blue"] = add_property_json("Curve: Blue", 0.0, "colorgrade_curve", curve_blue.Summary(requested_frame), NULL, 0.0, 1.0, false, requested_frame);
504  root["curve_blue"]["curve"] = curve_blue.JsonValue();
505  root["curve_blue"]["channel"] = "blue";
506  root["curve_blue"]["summary"] = curve_blue.Summary(requested_frame);
507 
508  root["lut_path"] = add_property_json("LUT File", 0.0, "string", lut_path, NULL, 0, 0, false, requested_frame);
509  root["lut_intensity"] = add_property_json("LUT Intensity", lut_intensity.GetValue(requested_frame), "float", "", &lut_intensity, 0.0, 1.0, false, requested_frame);
510 
511  return root.toStyledString();
512 }
openshot::ClipBase::add_property_json
Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, const Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame) const
Generate JSON for a property.
Definition: ClipBase.cpp:96
openshot::stringToJson
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:16
openshot::ColorGradeWheelEntry::GetAmount
float GetAmount(int64_t frame_number) const
Definition: ColorGrade.cpp:132
openshot::ColorGrade::wheels
ColorGradeWheelsData wheels
Definition: ColorGrade.h:97
openshot::ColorGradeWheelsData::midtones
ColorGradeWheelEntry midtones
Definition: ColorGrade.h:56
openshot::ColorGradeWheelEntry::SetJsonValue
void SetJsonValue(const Json::Value &root)
Definition: ColorGrade.cpp:106
openshot::ColorGradeWheelsData::Summary
std::string Summary(int64_t frame_number) const
Definition: ColorGrade.cpp:169
openshot::EffectBase::info
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:114
openshot::ColorGradeWheelsData::global
ColorGradeWheelEntry global
Definition: ColorGrade.h:54
openshot::ColorGrade::mix
Keyframe mix
Definition: ColorGrade.h:94
openshot::ColorGrade::curve_red
AnimatedCurve curve_red
Definition: ColorGrade.h:99
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: AnimatedCurve.h:24
ColorGrade.h
Header file for ColorGrade effect.
openshot::ColorGradeWheelsData::enabled
Keyframe enabled
Definition: ColorGrade.h:53
openshot::AnimatedCurve
Definition: AnimatedCurve.h:49
openshot::AnimatedCurve::BuildCurve
Keyframe BuildCurve(int64_t frame_number, double x_scale=1.0) const
Definition: AnimatedCurve.cpp:109
openshot::EffectBase::JsonValue
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: EffectBase.cpp:102
openshot::ColorMap::GetFrame
std::shared_ptr< openshot::Frame > GetFrame(int64_t frame_number) override
Apply effect to a new frame.
Definition: ColorMap.h:80
openshot::AnimatedCurve::enabled
Keyframe enabled
Definition: AnimatedCurve.h:54
openshot::ColorGrade::exposure
Keyframe exposure
Definition: ColorGrade.h:88
openshot::ColorGradeWheelEntry::amount
Keyframe amount
Definition: ColorGrade.h:38
openshot::AnimatedCurve::SetJsonValue
void SetJsonValue(const Json::Value &root)
Definition: AnimatedCurve.cpp:165
openshot::Keyframe::SetJsonValue
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: KeyFrame.cpp:372
openshot::ColorGrade::ColorGrade
ColorGrade()
Definition: ColorGrade.cpp:178
openshot::ColorGrade::SetJson
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: ColorGrade.cpp:421
openshot::ColorGrade::curve_all
AnimatedCurve curve_all
Definition: ColorGrade.h:98
openshot::ColorGradeWheelEntry::ColorGradeWheelEntry
ColorGradeWheelEntry()
Definition: ColorGrade.cpp:88
openshot::ColorGrade::tint
Keyframe tint
Definition: ColorGrade.h:87
openshot::ColorGrade::Json
std::string Json() const override
Generate JSON string of this object.
Definition: ColorGrade.cpp:395
openshot::Keyframe::JsonValue
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: KeyFrame.cpp:339
openshot::Color
This class represents a color (used on the timeline and clips)
Definition: Color.h:27
openshot::EffectBase::BasePropertiesJSON
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
Definition: EffectBase.cpp:245
openshot::ColorGrade::vibrance
Keyframe vibrance
Definition: ColorGrade.h:93
openshot::ColorGradeWheelEntry::luma
Keyframe luma
Definition: ColorGrade.h:39
openshot::Keyframe
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
Definition: KeyFrame.h:53
openshot::Color::SetJsonValue
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: Color.cpp:117
openshot::InvalidJSON
Exception for invalid JSON.
Definition: Exceptions.h:223
openshot::ColorMap::SetJsonValue
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: ColorMap.cpp:349
openshot::ColorGrade::saturation
Keyframe saturation
Definition: ColorGrade.h:92
openshot::ColorGrade::SetJsonValue
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: ColorGrade.cpp:430
openshot::ColorGrade::JsonValue
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: ColorGrade.cpp:399
openshot::EffectBase::InitEffectInfo
void InitEffectInfo()
Definition: EffectBase.cpp:42
openshot::Color::green
openshot::Keyframe green
Curve representing the green value (0 - 255)
Definition: Color.h:31
openshot::EffectInfoStruct::has_audio
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:44
openshot::ColorGrade::PropertiesJSON
std::string PropertiesJSON(int64_t requested_frame) const override
Definition: ColorGrade.cpp:471
openshot::ColorGrade::curve_green
AnimatedCurve curve_green
Definition: ColorGrade.h:100
openshot::ColorGradeWheelEntry
Wheel payload for a tonal region using native animated primitives.
Definition: ColorGrade.h:36
openshot::AnimatedCurve::JsonValue
Json::Value JsonValue() const
Definition: AnimatedCurve.cpp:148
openshot::ColorGradeWheelEntry::JsonValue
Json::Value JsonValue() const
Definition: ColorGrade.cpp:91
openshot::EffectInfoStruct::class_name
std::string class_name
The class name of the effect.
Definition: EffectBase.h:39
openshot::Color::JsonValue
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: Color.cpp:86
openshot::Keyframe::GetInt
int GetInt(int64_t index) const
Get the rounded INT value at a specific index.
Definition: KeyFrame.cpp:282
openshot::EffectInfoStruct::description
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:41
openshot::ColorGrade::curve_blue
AnimatedCurve curve_blue
Definition: ColorGrade.h:101
openshot::ColorGradeWheelsData::IsEnabled
bool IsEnabled(int64_t frame_number) const
Definition: ColorGrade.cpp:174
openshot::EffectInfoStruct::has_video
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:43
openshot::ColorGradeWheelsData::ColorGradeWheelsData
ColorGradeWheelsData()
Definition: ColorGrade.cpp:140
openshot::ColorGradeWheelEntry::color
Color color
Definition: ColorGrade.h:37
openshot::EffectInfoStruct::name
std::string name
The name of the effect.
Definition: EffectBase.h:40
openshot::Color::alpha
openshot::Keyframe alpha
Curve representing the alpha value (0 - 255)
Definition: Color.h:33
openshot::ColorGrade::shadows
Keyframe shadows
Definition: ColorGrade.h:91
openshot::ColorGrade::lut_intensity
Keyframe lut_intensity
Definition: ColorGrade.h:95
openshot::ColorGradeWheelEntry::GetColor
QColor GetColor(int64_t frame_number) const
Definition: ColorGrade.cpp:124
openshot::ColorGradeWheelsData::SetJsonValue
void SetJsonValue(const Json::Value &root)
Definition: ColorGrade.cpp:154
openshot::AnimatedCurve::Summary
std::string Summary(int64_t frame_number) const
Definition: AnimatedCurve.cpp:136
openshot::ColorGrade::highlights
Keyframe highlights
Definition: ColorGrade.h:90
openshot::Color::red
openshot::Keyframe red
Curve representing the red value (0 - 255)
Definition: Color.h:30
openshot::ColorGradeWheelEntry::GetLuma
float GetLuma(int64_t frame_number) const
Definition: ColorGrade.cpp:136
openshot::ColorGrade::temperature
Keyframe temperature
Definition: ColorGrade.h:86
openshot::ColorGradeWheelsData::JsonValue
Json::Value JsonValue() const
Definition: ColorGrade.cpp:143
openshot::ColorGradeWheelsData::shadows
ColorGradeWheelEntry shadows
Definition: ColorGrade.h:55
openshot::ColorGrade::GetFrame
std::shared_ptr< openshot::Frame > GetFrame(int64_t frame_number) override
This method is required for all derived classes of ClipBase, and returns a new openshot::Frame object...
Definition: ColorGrade.h:105
openshot::ColorGrade::contrast
Keyframe contrast
Definition: ColorGrade.h:89
openshot::Color::blue
openshot::Keyframe blue
Curve representing the red value (0 - 255)
Definition: Color.h:32
Exceptions.h
Header file for all Exception classes.
openshot::ColorGradeWheelsData::highlights
ColorGradeWheelEntry highlights
Definition: ColorGrade.h:57
openshot::EffectBase::SetJsonValue
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: EffectBase.cpp:146
openshot::Keyframe::GetValue
double GetValue(int64_t index) const
Get the value at a specific index.
Definition: KeyFrame.cpp:258