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
40using namespace openshot;
41
42/// Blank constructor, useful when using Json to load the effect properties
43Pixelate::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
49Pixelate::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
57void 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
72std::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
110std::string Pixelate::Json() const {
111
112 // Return formatted string
113 return JsonValue().toStyledString();
114}
115
116// Generate Json::Value for this object
117Json::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
133void 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
150void 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
169std::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
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 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
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