OpenShot Library | libopenshot  0.2.4
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 "../../include/effects/Pixelate.h"
32 
33 using namespace openshot;
34 
35 /// Blank constructor, useful when using Json to load the effect properties
36 Pixelate::Pixelate() : pixelization(0.7), left(0.0), top(0.0), right(0.0), bottom(0.0) {
37  // Init effect properties
38  init_effect_details();
39 }
40 
41 // Default constructor
43  pixelization(pixelization), left(left), top(top), right(right), bottom(bottom)
44 {
45  // Init effect properties
46  init_effect_details();
47 }
48 
49 // Init effect settings
50 void Pixelate::init_effect_details()
51 {
52  /// Initialize the values of the EffectInfo struct.
54 
55  /// Set the effect info
56  info.class_name = "Pixelate";
57  info.name = "Pixelate";
58  info.description = "Pixelate (increase or decrease) the number of visible pixels.";
59  info.has_audio = false;
60  info.has_video = true;
61 }
62 
63 // This method is required for all derived classes of EffectBase, and returns a
64 // modified openshot::Frame object
65 std::shared_ptr<Frame> Pixelate::GetFrame(std::shared_ptr<Frame> frame, int64_t frame_number)
66 {
67  // Get the frame's image
68  std::shared_ptr<QImage> frame_image = frame->GetImage();
69 
70  // Get current keyframe values
71  double pixelization_value = 1.0 - std::min(fabs(pixelization.GetValue(frame_number)), 1.0);
72  double left_value = left.GetValue(frame_number);
73  double top_value = top.GetValue(frame_number);
74  double right_value = right.GetValue(frame_number);
75  double bottom_value = bottom.GetValue(frame_number);
76 
77  if (pixelization_value > 0.0) {
78  // Resize frame image smaller (based on pixelization value)
79  std::shared_ptr<QImage> smaller_frame_image = std::shared_ptr<QImage>(new QImage(frame_image->scaledToWidth(std::max(frame_image->width() * pixelization_value, 2.0), Qt::SmoothTransformation)));
80 
81  // Resize image back to original size (with no smoothing to create pixelated image)
82  std::shared_ptr<QImage> pixelated_image = std::shared_ptr<QImage>(new QImage(smaller_frame_image->scaledToWidth(frame_image->width(), Qt::FastTransformation).convertToFormat(QImage::Format_RGBA8888)));
83 
84  // Get pixel array pointer
85  unsigned char *pixels = (unsigned char *) frame_image->bits();
86  unsigned char *pixelated_pixels = (unsigned char *) pixelated_image->bits();
87 
88  // Get pixels sizes of all margins
89  int top_bar_height = top_value * frame_image->height();
90  int bottom_bar_height = bottom_value * frame_image->height();
91  int left_bar_width = left_value * frame_image->width();
92  int right_bar_width = right_value * frame_image->width();
93 
94  // Loop through rows
95  for (int row = 0; row < frame_image->height(); row++) {
96 
97  // Copy pixelated pixels into original frame image (where needed)
98  if ((row >= top_bar_height) && (row <= frame_image->height() - bottom_bar_height)) {
99  memcpy(&pixels[(row * frame_image->width() + left_bar_width) * 4], &pixelated_pixels[(row * frame_image->width() + left_bar_width) * 4], sizeof(char) * (frame_image->width() - left_bar_width - right_bar_width) * 4);
100  }
101  }
102 
103  // Cleanup temp images
104  smaller_frame_image.reset();
105  pixelated_image.reset();
106  }
107 
108  // return the modified frame
109  return frame;
110 }
111 
112 // Generate JSON string of this object
113 std::string Pixelate::Json() {
114 
115  // Return formatted string
116  return JsonValue().toStyledString();
117 }
118 
119 // Generate Json::JsonValue for this object
120 Json::Value Pixelate::JsonValue() {
121 
122  // Create root json object
123  Json::Value root = EffectBase::JsonValue(); // get parent properties
124  root["type"] = info.class_name;
125  root["pixelization"] = pixelization.JsonValue();
126  root["left"] = left.JsonValue();
127  root["top"] = top.JsonValue();
128  root["right"] = right.JsonValue();
129  root["bottom"] = bottom.JsonValue();
130 
131  // return JsonValue
132  return root;
133 }
134 
135 // Load JSON string into this object
136 void Pixelate::SetJson(std::string value) {
137 
138  // Parse JSON string into JSON objects
139  Json::Value root;
140  Json::CharReaderBuilder rbuilder;
141  Json::CharReader* reader(rbuilder.newCharReader());
142 
143  std::string errors;
144  bool success = reader->parse( value.c_str(),
145  value.c_str() + value.size(), &root, &errors );
146  delete reader;
147 
148  if (!success)
149  // Raise exception
150  throw InvalidJSON("JSON could not be parsed (or is invalid)");
151 
152  try
153  {
154  // Set all values that match
155  SetJsonValue(root);
156  }
157  catch (const std::exception& e)
158  {
159  // Error parsing JSON (or missing keys)
160  throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
161  }
162 }
163 
164 // Load Json::JsonValue into this object
165 void Pixelate::SetJsonValue(Json::Value root) {
166 
167  // Set parent data
169 
170  // Set data from Json (if key is found)
171  if (!root["pixelization"].isNull())
172  pixelization.SetJsonValue(root["pixelization"]);
173  if (!root["left"].isNull())
174  left.SetJsonValue(root["left"]);
175  if (!root["top"].isNull())
176  top.SetJsonValue(root["top"]);
177  if (!root["right"].isNull())
178  right.SetJsonValue(root["right"]);
179  if (!root["bottom"].isNull())
180  bottom.SetJsonValue(root["bottom"]);
181 }
182 
183 // Get all properties for a specific frame
184 std::string Pixelate::PropertiesJSON(int64_t requested_frame) {
185 
186  // Generate JSON properties list
187  Json::Value root;
188  root["id"] = add_property_json("ID", 0.0, "string", Id(), NULL, -1, -1, true, requested_frame);
189  root["position"] = add_property_json("Position", Position(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame);
190  root["layer"] = add_property_json("Track", Layer(), "int", "", NULL, 0, 20, false, requested_frame);
191  root["start"] = add_property_json("Start", Start(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame);
192  root["end"] = add_property_json("End", End(), "float", "", NULL, 0, 1000 * 60 * 30, false, requested_frame);
193  root["duration"] = add_property_json("Duration", Duration(), "float", "", NULL, 0, 1000 * 60 * 30, true, requested_frame);
194 
195  // Keyframes
196  root["pixelization"] = add_property_json("Pixelization", pixelization.GetValue(requested_frame), "float", "", &pixelization, 0.0, 0.9999, false, requested_frame);
197  root["left"] = add_property_json("Left Margin", left.GetValue(requested_frame), "float", "", &left, 0.0, 1.0, false, requested_frame);
198  root["top"] = add_property_json("Top Margin", top.GetValue(requested_frame), "float", "", &top, 0.0, 1.0, false, requested_frame);
199  root["right"] = add_property_json("Right Margin", right.GetValue(requested_frame), "float", "", &right, 0.0, 1.0, false, requested_frame);
200  root["bottom"] = add_property_json("Bottom Margin", bottom.GetValue(requested_frame), "float", "", &bottom, 0.0, 1.0, false, requested_frame);
201 
202  // Return formatted string
203  return root.toStyledString();
204 }
Pixelate()
Blank constructor, useful when using Json to load the effect properties.
Definition: Pixelate.cpp:36
Keyframe bottom
Size of bottom margin.
Definition: Pixelate.h:65
Keyframe pixelization
Amount of pixelization.
Definition: Pixelate.h:61
float End()
Get end position (in seconds) of clip (trim end of video)
Definition: ClipBase.h:80
int Layer()
Get layer of clip on timeline (lower number is covered by higher numbers)
Definition: ClipBase.h:78
std::shared_ptr< Frame > GetFrame(std::shared_ptr< Frame > frame, int64_t frame_number)
This method is required for all derived classes of EffectBase, and returns a modified openshot::Frame...
Definition: Pixelate.cpp:65
virtual Json::Value JsonValue()=0
Generate Json::JsonValue for this object.
Definition: EffectBase.cpp:84
void SetJsonValue(Json::Value root)
Load Json::JsonValue into this object.
Definition: KeyFrame.cpp:374
std::string PropertiesJSON(int64_t requested_frame)
Definition: Pixelate.cpp:184
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:56
Keyframe right
Size of right margin.
Definition: Pixelate.h:64
std::string Id()
Get basic properties.
Definition: ClipBase.h:76
float Position()
Get position on timeline (in seconds)
Definition: ClipBase.h:77
Json::Value JsonValue()
Generate Json::JsonValue for this object.
Definition: Pixelate.cpp:120
void SetJsonValue(Json::Value root)
Load Json::JsonValue into this object.
Definition: Pixelate.cpp:165
virtual void SetJsonValue(Json::Value root)=0
Load Json::JsonValue into this object.
Definition: EffectBase.cpp:129
Keyframe top
Size of top margin.
Definition: Pixelate.h:63
std::string class_name
The class name of the effect.
Definition: EffectBase.h:52
std::string name
The name of the effect.
Definition: EffectBase.h:53
Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame)
Generate JSON for a property.
Definition: ClipBase.cpp:68
This namespace is the default namespace for all code in the openshot library.
Json::Value JsonValue() const
Generate Json::JsonValue for this object.
Definition: KeyFrame.cpp:329
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:54
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:55
Exception for invalid JSON.
Definition: Exceptions.h:205
double GetValue(int64_t index) const
Get the value at a specific index.
Definition: KeyFrame.cpp:262
void SetJson(std::string value)
Load JSON string into this object.
Definition: Pixelate.cpp:136
A Keyframe is a collection of Point instances, which is used to vary a number or property over time...
Definition: KeyFrame.h:64
std::string Json()
Get and Set JSON methods.
Definition: Pixelate.cpp:113
float Duration()
Get the length of this clip (in seconds)
Definition: ClipBase.h:81
float Start()
Get start position (in seconds) of clip (trim start of video)
Definition: ClipBase.h:79
Keyframe left
Size of left margin.
Definition: Pixelate.h:62
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:73