OpenShot Library | libopenshot 1.1.1
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
21using namespace openshot;
22
23namespace {
24constexpr float kInv255 = 1.0f / 255.0f;
25
26struct WheelBiasParams {
27 float red_delta;
28 float green_delta;
29 float blue_delta;
30};
31
32static inline float clamp01(float value) {
33 return std::max(0.0f, std::min(1.0f, value));
34}
35
36static 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
44static 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
49static std::string color_to_hex(const QColor& color) {
50 return color.name(QColor::HexRgb).toStdString();
51}
52
53static 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
68static 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
72static 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
88ColorGradeWheelEntry::ColorGradeWheelEntry()
89 : color(QColor(Qt::white)), amount(0.0f), luma(0.0f) {}
90
92 Json::Value root(Json::objectValue);
93 root["color"] = color_to_hex(QColor(
94 color.red.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
106void 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
124QColor 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
132float 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
136float 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
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
154void 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
169std::string ColorGradeWheelsData::Summary(int64_t frame_number) const {
170 return IsEnabled(frame_number) ? "Global / Shadows / Midtones / Highlights"
171 : "Disabled";
172}
173
174bool 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
195void ColorGrade::init_effect_details() {
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
204float ColorGrade::Clamp01(float value) {
205 return clamp01(value);
206}
207
208void 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
222std::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
395std::string ColorGrade::Json() const {
396 return JsonValue().toStyledString();
397}
398
399Json::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
421void 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
430void 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
471std::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}
Header file for ColorGrade effect.
Header file for all Exception classes.
void SetJsonValue(const Json::Value &root)
std::string Summary(int64_t frame_number) const
Keyframe BuildCurve(int64_t frame_number, double x_scale=1.0) const
Json::Value JsonValue() const
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:100
Keyframe lut_intensity
Definition: ColorGrade.h:95
Keyframe temperature
Definition: ColorGrade.h:86
AnimatedCurve curve_green
Definition: ColorGrade.h:100
AnimatedCurve curve_blue
Definition: ColorGrade.h:101
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: ColorGrade.cpp:399
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: ColorGrade.cpp:421
AnimatedCurve curve_red
Definition: ColorGrade.h:99
AnimatedCurve curve_all
Definition: ColorGrade.h:98
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
std::string Json() const override
Generate JSON string of this object.
Definition: ColorGrade.cpp:395
std::string PropertiesJSON(int64_t requested_frame) const override
Definition: ColorGrade.cpp:471
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: ColorGrade.cpp:430
ColorGradeWheelsData wheels
Definition: ColorGrade.h:97
std::shared_ptr< openshot::Frame > GetFrame(int64_t frame_number) override
Apply effect to a new frame.
Definition: ColorMap.h:80
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: ColorMap.cpp:349
This class represents a color (used on the timeline and clips)
Definition: Color.h:27
openshot::Keyframe blue
Curve representing the red value (0 - 255)
Definition: Color.h:32
openshot::Keyframe red
Curve representing the red value (0 - 255)
Definition: Color.h:30
openshot::Keyframe green
Curve representing the green value (0 - 255)
Definition: Color.h:31
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: Color.cpp:118
openshot::Keyframe alpha
Curve representing the alpha value (0 - 255)
Definition: Color.h:33
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: Color.cpp:87
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: EffectBase.cpp:106
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
Definition: EffectBase.cpp:261
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: EffectBase.cpp:150
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:114
Exception for invalid JSON.
Definition: Exceptions.h:224
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
Definition: KeyFrame.h:53
int GetInt(int64_t index) const
Get the rounded INT value at a specific index.
Definition: KeyFrame.cpp:282
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: KeyFrame.cpp:372
double GetValue(int64_t index) const
Get the value at a specific index.
Definition: KeyFrame.cpp:258
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: KeyFrame.cpp:339
This namespace is the default namespace for all code in the openshot library.
Definition: AnimatedCurve.h:24
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:16
Wheel payload for a tonal region using native animated primitives.
Definition: ColorGrade.h:36
QColor GetColor(int64_t frame_number) const
Definition: ColorGrade.cpp:124
float GetLuma(int64_t frame_number) const
Definition: ColorGrade.cpp:136
void SetJsonValue(const Json::Value &root)
Definition: ColorGrade.cpp:106
float GetAmount(int64_t frame_number) const
Definition: ColorGrade.cpp:132
Json::Value JsonValue() const
Definition: ColorGrade.cpp:91
std::string Summary(int64_t frame_number) const
Definition: ColorGrade.cpp:169
ColorGradeWheelEntry highlights
Definition: ColorGrade.h:57
ColorGradeWheelEntry global
Definition: ColorGrade.h:54
bool IsEnabled(int64_t frame_number) const
Definition: ColorGrade.cpp:174
void SetJsonValue(const Json::Value &root)
Definition: ColorGrade.cpp:154
ColorGradeWheelEntry midtones
Definition: ColorGrade.h:56
Json::Value JsonValue() const
Definition: ColorGrade.cpp:143
ColorGradeWheelEntry shadows
Definition: ColorGrade.h:55
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:43
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:44
std::string class_name
The class name of the effect.
Definition: EffectBase.h:39
std::string name
The name of the effect.
Definition: EffectBase.h:40
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:41