File: KeyFrame.h

package info (click to toggle)
libopenshot 0.5.0%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 31,228 kB
  • sloc: cpp: 32,692; python: 92; sh: 67; makefile: 21; ruby: 5
file content (153 lines) | stat: -rw-r--r-- 4,944 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/**
 * @file
 * @brief Header file for the Keyframe class
 * @author Jonathan Thomas <jonathan@openshot.org>
 *
 * @ref License
 */

// Copyright (c) 2008-2019 OpenShot Studios, LLC
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#ifndef OPENSHOT_KEYFRAME_H
#define OPENSHOT_KEYFRAME_H

#include <iostream>
#include <vector>

#include "Point.h"
#include "Json.h"

namespace openshot {

	/// Check if the X coordinate of a given Point is lower than a given value
	bool IsPointBeforeX(Point const & p, double const x);

	/// Linear interpolation between two points
	double InterpolateLinearCurve(Point const & left, Point const & right, double const target);

	/// Bezier interpolation between two points
	double InterpolateBezierCurve(Point const & left, Point const & right, double const target, double const allowed_error);

	/// Interpolate two points using the right Point's interpolation method
	double InterpolateBetween(Point const & left, Point const & right, double target, double allowed_error);

	/**
	 * @brief A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
	 *
	 * Keyframes are used to animate and interpolate values of properties over time.  For example, a single property
	 * can use a Keyframe instead of a constant value.  Assume you want to slide an image (from left to right) over
	 * a video.  You can create a Keyframe which will adjust the X value of the image over 100 frames (or however many
	 * frames the animation needs to last) from the value of 0 to 640.
	 *
	 * Please see the following <b>Example Code</b>:
	 * \code
	 * Keyframe k1;
	 * k1.AddPoint(Point(1,0));
	 * k1.AddPoint(Point(100,640));
	 *
	 * kf.PrintValues();
	 * \endcode
	 */
	class Keyframe {
	

	private:
		std::vector<Point> Points;	///< Vector of all Points

	public:
		/// Default constructor for the Keyframe class
		Keyframe() = default;

		/// Constructor which sets the default point & coordinate at X=1
		Keyframe(double value);

		/// Constructor which adds a supplied vector of Points
		Keyframe(const std::vector<openshot::Point>& points);

		/// Destructor
		~Keyframe();

		/// Add a new point on the key-frame.  Each point has a primary coordinate, a left handle, and a right handle.
		void AddPoint(Point p);

		/// Add a new point on the key-frame, with optional interpolation type
		void AddPoint(double x, double y, InterpolationType interpolate=BEZIER);

		/// Does this keyframe contain a specific point
		bool Contains(Point p) const;

		/// Flip all the points in this openshot::Keyframe (useful for reversing an effect or transition, etc...)
		void FlipPoints();

		/// Get the index of a point by matching a coordinate
		int64_t FindIndex(Point p) const;

		/// Get the value at a specific index
		double GetValue(int64_t index) const;

		/// Get the rounded INT value at a specific index
		int GetInt(int64_t index) const;

		/// Get the rounded LONG value at a specific index
		int64_t GetLong(int64_t index) const;

		/// Get the change in Y value (from the previous Y value)
		double GetDelta(int64_t index) const;

		/// Get a point at a specific index
		Point const & GetPoint(int64_t index) const;

		/// Get current point (or closest point to the right) from the X coordinate (i.e. the frame number)
		Point GetClosestPoint(Point p) const;

		/// Get current point (or closest point) from the X coordinate (i.e. the frame number)
		/// Either use the closest left point, or right point
		Point GetClosestPoint(Point p, bool useLeft) const;

		/// Get previous point (
		Point GetPreviousPoint(Point p) const;

		/// Get max point (by Y coordinate)
		Point GetMaxPoint() const;

		// Get the number of values (i.e. coordinates on the X axis)
		int64_t GetLength() const;

		/// Get the number of points (i.e. # of points)
		int64_t GetCount() const;

		/// Get the direction of the curve at a specific index (increasing or decreasing)
		bool IsIncreasing(int index) const;

		// Get and Set JSON methods
		std::string Json() const; ///< Generate JSON string of this object
		Json::Value JsonValue() const; ///< Generate Json::Value for this object
		void SetJson(const std::string value); ///< Load JSON string into this object
		void SetJsonValue(const Json::Value root); ///< Load Json::Value into this object

		/// Remove a point by matching a coordinate
		void RemovePoint(Point p);

		/// Remove a point by index
		void RemovePoint(int64_t index);

		/// Scale all points by a percentage (good for evenly lengthening or shortening an openshot::Keyframe)
		/// 1.0 = same size, 1.05 = 5% increase, etc...
		void ScalePoints(double scale);

		/// Replace an existing point with a new point
		void UpdatePoint(int64_t index, Point p);

		/// Print a list of points
		void PrintPoints(std::ostream* out=&std::cout) const;

		/// Print just the Y value of the point's primary coordinate
		void PrintValues(std::ostream* out=&std::cout) const;

	};

}

#endif