31 init_effect_details();
42 init_effect_details();
46void Sharpen::init_effect_details()
51 info.
description =
"Boost edge contrast to make video details look crisper.";
57static void boxes_for_gauss(
double sigma,
int b[3])
60 double wi = std::sqrt((12.0 * sigma * sigma / n) + 1.0);
61 int wl = int(std::floor(wi));
64 double mi = (12.0 * sigma * sigma - n*wl*wl - 4.0*n*wl - 3.0*n)
66 int m = int(std::round(mi));
67 for (
int i = 0; i < n; ++i)
68 b[i] = i < m ? wl : wu;
72static void blur_axis(
const QImage& src, QImage& dst,
int r,
bool vertical)
81 int bpl = src.bytesPerLine();
82 const uchar* in = src.bits();
83 uchar* out = dst.bits();
87 #pragma omp parallel for
88 for (
int y = 0; y < H; ++y) {
89 const uchar* rowIn = in + y*bpl;
90 uchar* rowOut = out + y*bpl;
91 double sB = rowIn[0]*(r+1), sG = rowIn[1]*(r+1),
92 sR = rowIn[2]*(r+1), sA = rowIn[3]*(r+1);
93 for (
int x = 1; x <= r; ++x) {
94 const uchar* p = rowIn + std::min(x, W-1)*4;
95 sB += p[0]; sG += p[1]; sR += p[2]; sA += p[3];
97 for (
int x = 0; x < W; ++x) {
98 uchar* o = rowOut + x*4;
99 o[0] = uchar(sB / window + 0.5);
100 o[1] = uchar(sG / window + 0.5);
101 o[2] = uchar(sR / window + 0.5);
102 o[3] = uchar(sA / window + 0.5);
104 const uchar* addP = rowIn + std::min(x+r+1, W-1)*4;
105 const uchar* subP = rowIn + std::max(x-r, 0)*4;
106 sB += addP[0] - subP[0];
107 sG += addP[1] - subP[1];
108 sR += addP[2] - subP[2];
109 sA += addP[3] - subP[3];
114 #pragma omp parallel for
115 for (
int x = 0; x < W; ++x) {
116 double sB = 0, sG = 0, sR = 0, sA = 0;
117 const uchar* p0 = in + x*4;
118 sB = p0[0]*(r+1); sG = p0[1]*(r+1);
119 sR = p0[2]*(r+1); sA = p0[3]*(r+1);
120 for (
int y = 1; y <= r; ++y) {
121 const uchar* p = in + std::min(y, H-1)*bpl + x*4;
122 sB += p[0]; sG += p[1]; sR += p[2]; sA += p[3];
124 for (
int y = 0; y < H; ++y) {
125 uchar* o = out + y*bpl + x*4;
126 o[0] = uchar(sB / window + 0.5);
127 o[1] = uchar(sG / window + 0.5);
128 o[2] = uchar(sR / window + 0.5);
129 o[3] = uchar(sA / window + 0.5);
131 const uchar* addP = in + std::min(y+r+1, H-1)*bpl + x*4;
132 const uchar* subP = in + std::max(y-r, 0)*bpl + x*4;
133 sB += addP[0] - subP[0];
134 sG += addP[1] - subP[1];
135 sR += addP[2] - subP[2];
136 sA += addP[3] - subP[3];
143static void box_blur(
const QImage& src, QImage& dst,
double rf,
bool vertical)
145 int r0 = int(std::floor(rf));
149 blur_axis(src, dst, r0, vertical);
152 QImage a(src.size(), QImage::Format_ARGB32);
153 QImage b(src.size(), QImage::Format_ARGB32);
154 blur_axis(src, a, r0, vertical);
155 blur_axis(src, b, r1, vertical);
157 int pixels = src.width() * src.height();
158 const uchar* pa = a.bits();
159 const uchar* pb = b.bits();
160 uchar* pd = dst.bits();
161 #pragma omp parallel for
162 for (
int i = 0; i < pixels; ++i) {
163 for (
int c = 0; c < 4; ++c) {
164 pd[i*4+c] = uchar((1.0 - f) * pa[i*4+c]
173static void gauss_blur(
const QImage& src, QImage& dst,
double sigma)
176 boxes_for_gauss(sigma, b);
177 QImage t1(src.size(), QImage::Format_ARGB32);
178 QImage t2(src.size(), QImage::Format_ARGB32);
180 double r = 0.5 * (b[0] - 1);
181 box_blur(src , t1, r,
false);
182 box_blur(t1, t2, r,
true);
184 r = 0.5 * (b[1] - 1);
185 box_blur(t2, t1, r,
false);
186 box_blur(t1, t2, r,
true);
188 r = 0.5 * (b[2] - 1);
189 box_blur(t2, t1, r,
false);
190 box_blur(t1, dst, r,
true);
195 std::shared_ptr<Frame> frame, int64_t frame_number)
197 auto img = frame->GetImage();
198 if (!
img ||
img->isNull())
200 if (
img->format() != QImage::Format_ARGB32)
201 *
img =
img->convertToFormat(QImage::Format_ARGB32);
203 int W =
img->width();
204 int H =
img->height();
205 if (
W <= 0 ||
H <= 0)
214 double sigma = std::max(0.1,
rpx *
H / 720.0);
221 int bplS =
img->bytesPerLine();
227 #pragma omp parallel for reduction(max:maxDY)
228 for (
int y = 0; y <
H; ++y) {
231 for (
int x = 0; x <
W; ++x) {
235 double dY = std::abs(0.114*
dB + 0.587*
dG + 0.299*
dR);
244 #pragma omp parallel for
245 for (
int y = 0; y <
H; ++y) {
248 for (
int x = 0; x <
W; ++x) {
256 double dY = 0.114*
dB + 0.587*
dG + 0.299*
dR;
259 if (std::abs(
dY) <
thr)
263 auto halo = [](
double d) {
264 return (255.0 - std::abs(
d)) / 255.0;
275 const double wB = 0.114,
wG = 0.587,
wR = 0.299;
306 for (
int c = 0;
c < 3; ++
c)
313 for (
int c = 0;
c < 3; ++
c)
325 for (
int c = 0;
c < 3; ++
c) {
385 "Mode",
mode,
"int",
"",
nullptr, 0, 1,
false, t);
389 "Channel",
channel,
"int",
"",
nullptr, 0, 2,
false, t);
393 return root.toStyledString();
Header file for all Exception classes.
Header file for Sharpen effect class.
Json::Value add_property_choice_json(std::string name, int value, int selected_value) const
Generate JSON choice for a property (dropdown properties)
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.
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
EffectInfoStruct info
Information about the current effect.
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
double GetValue(int64_t index) const
Get the value at a specific index.
Json::Value JsonValue() const
Generate Json::Value for this object.
int mode
Sharpening mode (0 = UnsharpMask, 1 = HighPassBlend)
std::string Json() const override
Get and Set JSON methods.
Keyframe radius
Radius of the blur used in sharpening (0 to 10 pixels for 1080p)
std::shared_ptr< Frame > GetFrame(std::shared_ptr< Frame > frame, int64_t frame_number) override
This method is required for all derived classes of EffectBase, and returns a modified openshot::Frame...
Json::Value JsonValue() const override
Generate Json::Value for this object.
Sharpen()
Default constructor.
void SetJson(const std::string value) override
Load JSON string into this object.
int channel
Channel to apply sharpening to (0 = All, 1 = Luma, 2 = Chroma)
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Keyframe amount
Amount of sharpening to apply (0 to 2)
std::string PropertiesJSON(int64_t requested_frame) const override
Keyframe threshold
Threshold for applying sharpening (0 to 1)
This namespace is the default namespace for all code in the openshot library.
const Json::Value stringToJson(const std::string value)
bool has_video
Determines if this effect manipulates the image of a frame.
bool has_audio
Determines if this effect manipulates the audio of a frame.
std::string class_name
The class name of the effect.
std::string name
The name of the effect.
std::string description
The description of this effect and what it does.