28 #include "../../include/effects/Blur.h" 33 Blur::Blur() : horizontal_radius(6.0), vertical_radius(6.0), sigma(3.0), iterations(3.0) {
35 init_effect_details();
44 init_effect_details();
48 void Blur::init_effect_details()
63 tr1::shared_ptr<Frame>
Blur::GetFrame(tr1::shared_ptr<Frame> frame,
long int frame_number)
66 tr1::shared_ptr<QImage> frame_image = frame->GetImage();
76 unsigned char *red =
new unsigned char[frame_image->width() * frame_image->height()]();
77 unsigned char *green =
new unsigned char[frame_image->width() * frame_image->height()]();
78 unsigned char *blue =
new unsigned char[frame_image->width() * frame_image->height()]();
79 unsigned char *alpha =
new unsigned char[frame_image->width() * frame_image->height()]();
81 unsigned char *blur_red =
new unsigned char[frame_image->width() * frame_image->height()]();
82 unsigned char *blur_green =
new unsigned char[frame_image->width() * frame_image->height()]();
83 unsigned char *blur_blue =
new unsigned char[frame_image->width() * frame_image->height()]();
84 unsigned char *blur_alpha =
new unsigned char[frame_image->width() * frame_image->height()]();
87 unsigned char *pixels = (
unsigned char *) frame_image->bits();
88 for (
int pixel = 0, byte_index=0; pixel < frame_image->width() * frame_image->height(); pixel++, byte_index+=4)
91 unsigned char R = pixels[byte_index];
92 unsigned char G = pixels[byte_index + 1];
93 unsigned char B = pixels[byte_index + 2];
94 unsigned char A = pixels[byte_index + 3];
104 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_red[i] = red[i];
105 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_green[i] = green[i];
106 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_blue[i] = blue[i];
107 for (
int i = 0; i < (frame_image->width() * frame_image->height()); i++) blur_alpha[i] = alpha[i];
110 for (
int iteration = 0; iteration < iteration_value; iteration++)
113 if (horizontal_radius_value > 0.0) {
115 int *bxs = initBoxes(sigma_value, horizontal_radius_value);
118 boxBlurH(red, blur_red, frame_image->width(), frame_image->height(), horizontal_radius_value);
119 boxBlurH(green, blur_green, frame_image->width(), frame_image->height(), horizontal_radius_value);
120 boxBlurH(blue, blur_blue, frame_image->width(), frame_image->height(), horizontal_radius_value);
121 boxBlurH(alpha, blur_alpha, frame_image->width(), frame_image->height(), horizontal_radius_value);
128 if (vertical_radius_value > 0.0) {
130 int *bxs = initBoxes(sigma_value, vertical_radius_value);
133 boxBlurT(red, blur_red, frame_image->width(), frame_image->height(), vertical_radius_value);
134 boxBlurT(green, blur_green, frame_image->width(), frame_image->height(), vertical_radius_value);
135 boxBlurT(blue, blur_blue, frame_image->width(), frame_image->height(), vertical_radius_value);
136 boxBlurT(alpha, blur_alpha, frame_image->width(), frame_image->height(), vertical_radius_value);
144 for (
int pixel = 0, byte_index=0; pixel < frame_image->width() * frame_image->height(); pixel++, byte_index+=4)
147 unsigned char R = blur_red[pixel];
148 unsigned char G = blur_green[pixel];
149 unsigned char B = blur_blue[pixel];
150 unsigned char A = blur_alpha[pixel];
153 pixels[byte_index] = R;
154 pixels[byte_index + 1] = G;
155 pixels[byte_index + 2] = B;
156 pixels[byte_index + 3] = A;
174 int* Blur::initBoxes(
float sigma,
int n)
176 float wIdeal = sqrt((12.0 *
sigma *
sigma / n) + 1.0);
177 int wl = floor(wIdeal);
178 if (wl % 2 == 0) wl--;
181 float mIdeal = (12.0 *
sigma *
sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4.0 * wl - 4);
182 int m = round(mIdeal);
184 int *sizes =
new int[n]();
185 for (
int i = 0; i < n; i++) sizes[i] = i < m ? wl : wu;
190 void Blur::boxBlurH(
unsigned char *scl,
unsigned char *tcl,
int w,
int h,
int r) {
191 float iarr = 1.0 / (r + r + 1);
192 for (
int i = 0; i < h; i++) {
193 int ti = i * w, li = ti, ri = ti + r;
194 int fv = scl[ti], lv = scl[ti + w - 1], val = (r + 1) * fv;
195 for (
int j = 0; j < r; j++) val += scl[ti + j];
196 for (
int j = 0; j <= r; j++) {
197 val += scl[ri++] - fv;
198 tcl[ti++] = round(val * iarr);
200 for (
int j = r + 1; j < w - r; j++) {
201 val += scl[ri++] - scl[li++];
202 tcl[ti++] = round(val * iarr);
204 for (
int j = w - r; j < w; j++) {
205 val += lv - scl[li++];
206 tcl[ti++] = round(val * iarr);
211 void Blur::boxBlurT(
unsigned char *scl,
unsigned char *tcl,
int w,
int h,
int r) {
212 float iarr = 1.0 / (r + r + 1);
213 for (
int i = 0; i < w; i++) {
214 int ti = i, li = ti, ri = ti + r * w;
215 int fv = scl[ti], lv = scl[ti + w * (h - 1)], val = (r + 1) * fv;
216 for (
int j = 0; j < r; j++) val += scl[ti + j * w];
217 for (
int j = 0; j <= r; j++) {
219 tcl[ti] = round(val * iarr);
223 for (
int j = r + 1; j < h - r; j++) {
224 val += scl[ri] - scl[li];
225 tcl[ti] = round(val * iarr);
230 for (
int j = h - r; j < h; j++) {
232 tcl[ti] = round(val * iarr);
267 bool success = reader.parse( value, root );
270 throw InvalidJSON(
"JSON could not be parsed (or is invalid)",
"");
280 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)",
"");
291 if (!root[
"horizontal_radius"].isNull())
293 else if (!root[
"vertical_radius"].isNull())
295 else if (!root[
"sigma"].isNull())
297 else if (!root[
"iterations"].isNull())
305 Point requested_point(requested_frame, requested_frame);
309 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(),
false, 0, -1, -1,
CONSTANT, -1,
true);
310 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"",
false, 0, 0, 1000 * 60 * 30,
CONSTANT, -1,
false);
311 root[
"layer"] =
add_property_json(
"Track",
Layer(),
"int",
"",
false, 0, 0, 20,
CONSTANT, -1,
false);
312 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"",
false, 0, 0, 1000 * 60 * 30,
CONSTANT, -1,
false);
313 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"",
false, 0, 0, 1000 * 60 * 30,
CONSTANT, -1,
false);
314 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"",
false, 0, 0, 1000 * 60 * 30,
CONSTANT, -1,
true);
317 root[
"horizontal_radius"] =
add_property_json(
"Horizontal Radius",
horizontal_radius.
GetValue(requested_frame),
"float",
"",
horizontal_radius.
Contains(requested_point),
horizontal_radius.
GetCount(), 0, 100,
horizontal_radius.
GetClosestPoint(requested_point).
interpolation,
horizontal_radius.
GetClosestPoint(requested_point).
co.
X,
false);
318 root[
"vertical_radius"] =
add_property_json(
"Vertical Radius",
vertical_radius.
GetValue(requested_frame),
"float",
"",
vertical_radius.
Contains(requested_point),
vertical_radius.
GetCount(), 0, 100,
vertical_radius.
GetClosestPoint(requested_point).
interpolation,
vertical_radius.
GetClosestPoint(requested_point).
co.
X,
false);
319 root[
"sigma"] =
add_property_json(
"Sigma",
sigma.
GetValue(requested_frame),
"float",
"",
sigma.
Contains(requested_point),
sigma.
GetCount(), 0, 100,
sigma.
GetClosestPoint(requested_point).
interpolation,
sigma.
GetClosestPoint(requested_point).
co.
X,
false);
320 root[
"iterations"] =
add_property_json(
"Iterations",
iterations.
GetValue(requested_frame),
"float",
"",
iterations.
Contains(requested_point),
iterations.
GetCount(), 0, 100,
iterations.
GetClosestPoint(requested_point).
interpolation,
iterations.
GetClosestPoint(requested_point).
co.
X,
false);
323 return root.toStyledString();
string Json()
Get and Set JSON methods.
Json::Value JsonValue()
Generate Json::JsonValue for this object.
Json::Value JsonValue()
Generate Json::JsonValue for this object.
InterpolationType interpolation
This is the interpolation mode.
bool Contains(Point p)
Does this keyframe contain a specific point.
float End()
Get end position (in seconds) of clip (trim end of video)
A Point is the basic building block of a key-frame curve.
int Layer()
Get layer of clip on timeline (lower number is covered by higher numbers)
Keyframe iterations
Iterations keyframe. The # of blur iterations per pixel. 3 iterations = Gaussian. ...
string class_name
The class name of the effect.
virtual Json::Value JsonValue()=0
Generate Json::JsonValue for this object.
void SetJsonValue(Json::Value root)
Load Json::JsonValue into this object.
bool has_audio
Determines if this effect manipulates the audio of a frame.
float GetValue(long int index)
Get the value at a specific index.
Json::Value add_property_json(string name, float value, string type, string memo, bool contains_point, int number_of_points, float min_value, float max_value, InterpolationType intepolation, int closest_point_x, bool readonly)
Generate JSON for a property.
string Id()
Get basic properties.
float Position()
Get position on timeline (in seconds)
string name
The name of the effect.
Keyframe vertical_radius
Vertical blur radius keyframe. The size of the vertical blur operation in pixels. ...
void SetJsonValue(Json::Value root)
Load Json::JsonValue into this object.
string description
The description of this effect and what it does.
virtual void SetJsonValue(Json::Value root)=0
Load Json::JsonValue into this object.
float X
The X value of the coordinate (usually representing the frame #)
Blur()
Blank constructor, useful when using Json to load the effect properties.
Point GetClosestPoint(Point p)
Get current point (or closest point) from the X coordinate (i.e. the frame number) ...
void SetJson(string value)
Load JSON string into this object.
int GetInt(long int index)
Get the rounded INT value at a specific index.
This namespace is the default namespace for all code in the openshot library.
long int GetCount()
Get the number of points (i.e. # of points)
Coordinate co
This is the primary coordinate.
string PropertiesJSON(long int requested_frame)
bool has_video
Determines if this effect manipulates the image of a frame.
Exception for invalid JSON.
A Keyframe is a collection of Point instances, which is used to vary a number or property over time...
float Duration()
Get the length of this clip (in seconds)
Constant curves jump from their previous position to a new one (with no interpolation).
Keyframe sigma
Sigma keyframe. The amount of spread in the blur operation. Should be larger than radius...
tr1::shared_ptr< Frame > GetFrame(tr1::shared_ptr< Frame > frame, long int frame_number)
This method is required for all derived classes of EffectBase, and returns a modified openshot::Frame...
float Start()
Get start position (in seconds) of clip (trim start of video)
Keyframe horizontal_radius
Horizontal blur radius keyframe. The size of the horizontal blur operation in pixels.
EffectInfoStruct info
Information about the current effect.