OpenShot Library | libopenshot  0.2.6
Pixelate.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Source file for Pixelate effect class
4  * @author Jonathan Thomas <jonathan@openshot.org>
5  *
6  * @ref License
7  */
8 
9 /* LICENSE
10  *
11  * Copyright (c) 2008-2019 OpenShot Studios, LLC
12  * <http://www.openshotstudios.com/>. This file is part of
13  * OpenShot Library (libopenshot), an open-source project dedicated to
14  * delivering high quality video editing and animation solutions to the
15  * world. For more information visit <http://www.openshot.org/>.
16  *
17  * OpenShot Library (libopenshot) is free software: you can redistribute it
18  * and/or modify it under the terms of the GNU Lesser General Public License
19  * as published by the Free Software Foundation, either version 3 of the
20  * License, or (at your option) any later version.
21  *
22  * OpenShot Library (libopenshot) is distributed in the hope that it will be
23  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU Lesser General Public License for more details.
26  *
27  * You should have received a copy of the GNU Lesser General Public License
28  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #include "Pixelate.h"
32 #include "Exceptions.h"
33 #include "Json.h"
34 
35 #include <QImage>
36 #include <QPainter>
37 #include <QRect>
38 #include <QPoint>
39 
40 using namespace openshot;
41 
42 /// Blank constructor, useful when using Json to load the effect properties
43 Pixelate::Pixelate() : pixelization(0.5), left(0.0), top(0.0), right(0.0), bottom(0.0) {
44  // Init effect properties
45  init_effect_details();
46 }
47 
48 // Default constructor
50  pixelization(pixelization), left(left), top(top), right(right), bottom(bottom)
51 {
52  // Init effect properties
53  init_effect_details();
54 }
55 
56 // Init effect settings
57 void Pixelate::init_effect_details()
58 {
59  /// Initialize the values of the EffectInfo struct.
61 
62  /// Set the effect info
63  info.class_name = "Pixelate";
64  info.name = "Pixelate";
65  info.description = "Pixelate (increase or decrease) the number of visible pixels.";
66  info.has_audio = false;
67  info.has_video = true;
68 }
69 
70 // This method is required for all derived classes of EffectBase, and returns a
71 // modified openshot::Frame object
72 std::shared_ptr<Frame> Pixelate::GetFrame(std::shared_ptr<Frame> frame, int64_t frame_number)
73 {
74  // Get the frame's image
75  std::shared_ptr<QImage> frame_image = frame->GetImage();
76 
77  // Get current keyframe values
78  double pixelization_value = std::min(pow(0.001, fabs(pixelization.GetValue(frame_number))), 1.0);
79  double left_value = left.GetValue(frame_number);
80  double top_value = top.GetValue(frame_number);
81  double right_value = right.GetValue(frame_number);
82  double bottom_value = bottom.GetValue(frame_number);
83 
84  if (pixelization_value > 0.0) {
85  int w = frame_image->width();
86  int h = frame_image->height();
87 
88  // Define area we're working on in terms of a QRect with QMargins applied
89  QRect area(QPoint(0,0), frame_image->size());
90  area = area.marginsRemoved({int(left_value * w), int(top_value * h), int(right_value * w), int(bottom_value * h)});
91 
92  int scale_to = (int) (area.width() * pixelization_value);
93  if (scale_to < 1) {
94  scale_to = 1; // Not less than one pixel
95  }
96  // Copy and scale pixels in area to be pixelated
97  auto frame_scaled = frame_image->copy(area).scaledToWidth(scale_to, Qt::SmoothTransformation);
98 
99  // Draw pixelated image back over original
100  QPainter painter(frame_image.get());
101  painter.drawImage(area, frame_scaled);
102  painter.end();
103  }
104 
105  // return the modified frame
106  return frame;
107 }
108 
109 // Generate JSON string of this object
110 std::string Pixelate::Json() const {
111 
112  // Return formatted string
113  return JsonValue().toStyledString();
114 }
115 
116 // Generate Json::Value for this object
117 Json::Value Pixelate::JsonValue() const {
118 
119  // Create root json object
120  Json::Value root = EffectBase::JsonValue(); // get parent properties
121  root["type"] = info.class_name;
122  root["pixelization"] = pixelization.JsonValue();
123  root["left"] = left.JsonValue();
124  root["top"] = top.JsonValue();
125  root["right"] = right.JsonValue();
126  root["bottom"] = bottom.JsonValue();
127 
128  // return JsonValue
129  return root;
130 }
131 
132 // Load JSON string into this object
133 void Pixelate::SetJson(const std::string value) {
134 
135  // Parse JSON string into JSON objects
136  try
137  {
138  const Json::Value root = openshot::stringToJson(value);
139  // Set all values that match
140  SetJsonValue(root);
141  }
142  catch (const std::exception& e)
143  {
144  // Error parsing JSON (or missing keys)
145  throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
146  }
147 }
148 
149 // Load Json::Value into this object
150 void Pixelate::SetJsonValue(const Json::Value root) {
151 
152  // Set parent data
154 
155  // Set data from Json (if key is found)
156  if (!root["pixelization"].isNull())
157  pixelization.SetJsonValue(root["pixelization"]);
158  if (!root["left"].isNull())
159  left.SetJsonValue(root["left"]);
160  if (!root["top"].isNull())
161  top.SetJsonValue(root["top"]);
162  if (!root["right"].isNull())
163  right.SetJsonValue(root["right"]);
164  if (!root["bottom"].isNull())
165  bottom.SetJsonValue(root["bottom"]);
166 }
167 
168 // Get all properties for a specific frame
169 std::string Pixelate::PropertiesJSON(int64_t requested_frame) const {
170 
171  // Generate JSON properties list
172  Json::Value root;
173  root["id"] = add_property_json("ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame);
174  root["position"] = add_property_json("Position", Position(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame);
175  root["layer"] = add_property_json("Track", Layer(), "int", "", NULL, 0, 20, false, requested_frame);
176  root["start"] = add_property_json("Start", Start(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame);
177  root["end"] = add_property_json("End", End(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame);
178  root["duration"] = add_property_json("Duration", Duration(), "float", "", NULL, 0, 1000 * 60 * 30, true, requested_frame);
179 
180  // Keyframes
181  root["pixelization"] = add_property_json("Pixelization", pixelization.GetValue(requested_frame), "float", "", &pixelization, 0.0, 0.9999, false, requested_frame);
182  root["left"] = add_property_json("Left Margin", left.GetValue(requested_frame), "float", "", &left, 0.0, 1.0, false, requested_frame);
183  root["top"] = add_property_json("Top Margin", top.GetValue(requested_frame), "float", "", &top, 0.0, 1.0, false, requested_frame);
184  root["right"] = add_property_json("Right Margin", right.GetValue(requested_frame), "float", "", &right, 0.0, 1.0, false, requested_frame);
185  root["bottom"] = add_property_json("Bottom Margin", bottom.GetValue(requested_frame), "float", "", &bottom, 0.0, 1.0, false, requested_frame);
186 
187  // Set the parent effect which properties this effect will inherit
188  root["parent_effect_id"] = add_property_json("Parent", 0.0, "string", info.parent_effect_id, NULL, -1, -1, false, requested_frame);
189 
190  // Return formatted string
191  return root.toStyledString();
192 }
Pixelate()
Default constructor, useful when using Json to load the effect properties.
Definition: Pixelate.cpp:43
Keyframe bottom
Size of bottom margin.
Definition: Pixelate.h:64
std::string Id() const
Get the Id of this clip object.
Definition: ClipBase.h:107
float Start() const
Get start position (in seconds) of clip (trim start of video)
Definition: ClipBase.h:110
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: EffectBase.cpp:127
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: Pixelate.cpp:133
Keyframe pixelization
Amount of pixelization.
Definition: Pixelate.h:60
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:34
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: EffectBase.cpp:92
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:59
Header file for all Exception classes.
Keyframe right
Size of right margin.
Definition: Pixelate.h:63
Header file for JSON class.
std::string PropertiesJSON(int64_t requested_frame) const override
Definition: Pixelate.cpp:169
Keyframe top
Size of top margin.
Definition: Pixelate.h:62
std::string class_name
The class name of the effect.
Definition: EffectBase.h:54
std::string name
The name of the effect.
Definition: EffectBase.h:55
float Duration() const
Get the length of this clip (in seconds)
Definition: ClipBase.h:112
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: KeyFrame.cpp:368
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:46
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: KeyFrame.cpp:335
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:56
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:58
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: Pixelate.cpp:117
Exception for invalid JSON.
Definition: Exceptions.h:205
double GetValue(int64_t index) const
Get the value at a specific index.
Definition: KeyFrame.cpp:268
std::string parent_effect_id
Id of the parent effect (if there is one)
Definition: EffectBase.h:57
std::string Json() const override
Generate JSON string of this object.
Definition: Pixelate.cpp:110
float Position() const
Get position on timeline (in seconds)
Definition: ClipBase.h:108
float End() const
Get end position (in seconds) of clip (trim end of video)
Definition: ClipBase.h:111
A Keyframe is a collection of Point instances, which is used to vary a number or property over time...
Definition: KeyFrame.h:72
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:68
Header file for Pixelate effect class.
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: Pixelate.h:84
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: Pixelate.cpp:150
int Layer() const
Get layer of clip on timeline (lower number is covered by higher numbers)
Definition: ClipBase.h:109
Keyframe left
Size of left margin.
Definition: Pixelate.h:61
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:87