OpenShot Library | libopenshot  0.2.7
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
49 Pixelate::Pixelate(Keyframe pixelization, Keyframe left, Keyframe top, Keyframe right, Keyframe bottom) :
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 }
Header file for all Exception classes.
Header file for JSON class.
Header file for Pixelate effect class.
float End() const
Get end position (in seconds) of clip (trim end of video)
Definition: ClipBase.h:111
float Start() const
Get start position (in seconds) of clip (trim start of video)
Definition: ClipBase.h:110
float Duration() const
Get the length of this clip (in seconds)
Definition: ClipBase.h:112
std::string Id() const
Get the Id of this clip object.
Definition: ClipBase.h:107
int Layer() const
Get layer of clip on timeline (lower number is covered by higher numbers)
Definition: ClipBase.h:109
float Position() const
Get position on timeline (in seconds)
Definition: ClipBase.h:108
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
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: EffectBase.cpp:92
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: EffectBase.cpp:127
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:87
Exception for invalid JSON.
Definition: Exceptions.h:206
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
Definition: KeyFrame.h:72
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: KeyFrame.cpp:368
double GetValue(int64_t index) const
Get the value at a specific index.
Definition: KeyFrame.cpp:268
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: KeyFrame.cpp:335
Pixelate()
Default constructor, useful when using Json to load the effect properties.
Definition: Pixelate.cpp:43
Keyframe right
Size of right margin.
Definition: Pixelate.h:63
std::string Json() const override
Generate JSON string of this object.
Definition: Pixelate.cpp:110
std::string PropertiesJSON(int64_t requested_frame) const override
Definition: Pixelate.cpp:169
Keyframe pixelization
Amount of pixelization.
Definition: Pixelate.h:60
Keyframe left
Size of left margin.
Definition: Pixelate.h:61
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: Pixelate.cpp:117
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: Pixelate.cpp:133
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: Pixelate.cpp:150
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
Keyframe top
Size of top margin.
Definition: Pixelate.h:62
Keyframe bottom
Size of bottom margin.
Definition: Pixelate.h:64
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:47
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:34
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:58
std::string parent_effect_id
Id of the parent effect (if there is one)
Definition: EffectBase.h:57
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:59
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
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:56