31 #include "../../include/effects/Blur.h"
36 Blur::Blur() : horizontal_radius(6.0), vertical_radius(6.0), sigma(3.0), iterations(3.0) {
38 init_effect_details();
43 horizontal_radius(new_horizontal_radius), vertical_radius(new_vertical_radius),
44 sigma(new_sigma), iterations(new_iterations)
47 init_effect_details();
51 void Blur::init_effect_details()
66 std::shared_ptr<Frame>
Blur::GetFrame(std::shared_ptr<Frame> frame, int64_t frame_number)
69 std::shared_ptr<QImage> frame_image = frame->
GetImage();
77 int w = frame_image->width();
78 int h = frame_image->height();
81 QImage image_copy = frame_image->copy();
82 std::shared_ptr<QImage> frame_image_2 = std::make_shared<QImage>(image_copy);
85 for (
int iteration = 0; iteration < iteration_value; ++iteration)
88 if (horizontal_radius_value > 0.0) {
90 boxBlurH(frame_image->bits(), frame_image_2->bits(), w, h, horizontal_radius_value);
93 frame_image.swap(frame_image_2);
97 if (vertical_radius_value > 0.0) {
99 boxBlurT(frame_image->bits(), frame_image_2->bits(), w, h, vertical_radius_value);
102 frame_image.swap(frame_image_2);
112 void Blur::boxBlurH(
unsigned char *scl,
unsigned char *tcl,
int w,
int h,
int r) {
113 float iarr = 1.0 / (r + r + 1);
115 #pragma omp parallel for shared (scl, tcl)
116 for (
int i = 0; i < h; ++i) {
117 for (
int ch = 0; ch < 4; ++ch) {
118 int ti = i * w, li = ti, ri = ti + r;
119 int fv = scl[ti * 4 + ch], lv = scl[(ti + w - 1) * 4 + ch], val = (r + 1) * fv;
120 for (
int j = 0; j < r; ++j) {
121 val += scl[(ti + j) * 4 + ch];
123 for (
int j = 0; j <= r; ++j) {
124 val += scl[ri++ * 4 + ch] - fv;
125 tcl[ti++ * 4 + ch] = round(val * iarr);
127 for (
int j = r + 1; j < w - r; ++j) {
128 val += scl[ri++ * 4 + ch] - scl[li++ * 4 + ch];
129 tcl[ti++ * 4 + ch] = round(val * iarr);
131 for (
int j = w - r; j < w; ++j) {
132 val += lv - scl[li++ * 4 + ch];
133 tcl[ti++ * 4 + ch] = round(val * iarr);
139 void Blur::boxBlurT(
unsigned char *scl,
unsigned char *tcl,
int w,
int h,
int r) {
140 float iarr = 1.0 / (r + r + 1);
142 #pragma omp parallel for shared (scl, tcl)
143 for (
int i = 0; i < w; i++) {
144 for (
int ch = 0; ch < 4; ++ch) {
145 int ti = i, li = ti, ri = ti + r * w;
146 int fv = scl[ti * 4 + ch], lv = scl[(ti + w * (h - 1)) * 4 + ch], val = (r + 1) * fv;
147 for (
int j = 0; j < r; j++) val += scl[(ti + j * w) * 4 + ch];
148 for (
int j = 0; j <= r; j++) {
149 val += scl[ri * 4 + ch] - fv;
150 tcl[ti * 4 + ch] = round(val * iarr);
154 for (
int j = r + 1; j < h - r; j++) {
155 val += scl[ri * 4 + ch] - scl[li * 4 + ch];
156 tcl[ti * 4 + ch] = round(val * iarr);
161 for (
int j = h - r; j < h; j++) {
162 val += lv - scl[li * 4 + ch];
163 tcl[ti * 4 + ch] = round(val * iarr);
203 catch (
const std::exception& e)
206 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
217 if (!root[
"horizontal_radius"].isNull())
219 if (!root[
"vertical_radius"].isNull())
221 if (!root[
"sigma"].isNull())
223 if (!root[
"iterations"].isNull())
232 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
233 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
235 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
236 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"", NULL, 0, 1000 * 60 * 30,
false, requested_frame);
237 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"", NULL, 0, 1000 * 60 * 30,
true, requested_frame);
246 return root.toStyledString();