28 #include "../../include/effects/Mask.h" 35 init_effect_details();
43 init_effect_details();
47 void Mask::init_effect_details()
54 info.
name =
"Alpha Mask / Wipe Transition";
55 info.
description =
"Uses a grayscale mask image to gradually wipe / transition between 2 images.";
61 int Mask::constrain(
int color_value)
66 else if (color_value > 255)
73 void Mask::set_grayscale_mask(tr1::shared_ptr<QImage> mask_frame_image,
int width,
int height,
float brightness,
float contrast)
76 unsigned char *pixels = (
unsigned char *) mask_frame_image->bits();
80 for (
int pixel = 0, byte_index=0; pixel < mask_frame_image->width() * mask_frame_image->height(); pixel++, byte_index+=4)
83 int R = pixels[byte_index];
84 int G = pixels[byte_index + 1];
85 int B = pixels[byte_index + 2];
88 int gray_value = qGray(R, G, B);
91 int factor = (259 * (contrast + 255)) / (255 * (259 -
contrast));
92 gray_value = constrain((factor * (gray_value - 128)) + 128);
98 gray_value = constrain(gray_value);
101 pixels[byte_index] = gray_value;
102 pixels[byte_index + 1] = gray_value;
103 pixels[byte_index + 2] = gray_value;
104 pixels[byte_index + 3] = 255;
110 tr1::shared_ptr<Frame>
Mask::GetFrame(tr1::shared_ptr<Frame> frame,
long int frame_number)
113 tr1::shared_ptr<QImage> frame_image = frame->GetImage();
116 if (reader && !reader->
IsOpen())
117 #pragma omp critical (open_mask_reader)
126 #pragma omp critical (open_mask_reader) 129 tr1::shared_ptr<QImage> mask_without_sizing = tr1::shared_ptr<QImage>(
new QImage(*reader->
GetFrame(frame_number)->GetImage()));
132 original_mask = tr1::shared_ptr<QImage>(
new QImage(
133 mask_without_sizing->scaled(frame_image->width(), frame_image->height(), Qt::IgnoreAspectRatio,
134 Qt::SmoothTransformation)));
139 tr1::shared_ptr<QImage> mask = tr1::shared_ptr<QImage>(
new QImage(*original_mask));
140 set_grayscale_mask(mask, frame_image->width(), frame_image->height(), brightness.GetValue(frame_number), contrast.GetValue(frame_number));
143 unsigned char *pixels = (
unsigned char *) frame_image->bits();
144 unsigned char *mask_pixels = (
unsigned char *) mask->bits();
148 for (
int pixel = 0, byte_index=0; pixel < frame_image->width() * frame_image->height(); pixel++, byte_index+=4)
151 int Frame_Alpha = pixels[byte_index + 3];
152 int Mask_Value = constrain(Frame_Alpha - (
int)mask_pixels[byte_index]);
155 pixels[byte_index + 3] = Mask_Value;
160 frame->AddImage(mask);
179 root[
"brightness"] = brightness.JsonValue();
180 root[
"contrast"] = contrast.JsonValue();
184 root[
"reader"] = Json::objectValue;
197 bool success = reader.parse( value, root );
200 throw InvalidJSON(
"JSON could not be parsed (or is invalid)",
"");
210 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)",
"");
221 if (!root[
"replace_image"].isNull())
223 if (!root[
"brightness"].isNull())
224 brightness.SetJsonValue(root[
"brightness"]);
225 if (!root[
"contrast"].isNull())
226 contrast.SetJsonValue(root[
"contrast"]);
227 if (!root[
"reader"].isNull())
230 if (!root[
"reader"][
"type"].isNull())
242 string type = root[
"reader"][
"type"].asString();
244 if (type ==
"FFmpegReader") {
247 reader =
new FFmpegReader(root[
"reader"][
"path"].asString());
250 #ifdef USE_IMAGEMAGICK 251 }
else if (type ==
"ImageReader") {
254 reader =
new ImageReader(root[
"reader"][
"path"].asString());
258 }
else if (type ==
"QtImageReader") {
261 reader =
new QtImageReader(root[
"reader"][
"path"].asString());
264 }
else if (type ==
"ChunkReader") {
267 reader =
new ChunkReader(root[
"reader"][
"path"].asString(), (
ChunkVersion) root[
"reader"][
"chunk_version"].asInt());
281 Point requested_point(requested_frame, requested_frame);
285 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(),
false, 0, -1, -1,
CONSTANT, -1,
true);
286 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"",
false, 0, 0, 30 * 60 * 60 * 48,
CONSTANT, -1,
false);
287 root[
"layer"] =
add_property_json(
"Track",
Layer(),
"int",
"",
false, 0, 0, 20,
CONSTANT, -1,
false);
288 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"",
false, 0, 0, 30 * 60 * 60 * 48,
CONSTANT, -1,
false);
289 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"",
false, 0, 0, 30 * 60 * 60 * 48,
CONSTANT, -1,
false);
290 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"",
false, 0, 0, 30 * 60 * 60 * 48,
CONSTANT, -1,
true);
291 root[
"replace_image"] =
add_property_json(
"Replace Image",
replace_image,
"int",
"",
false, 0, 0, 1,
CONSTANT, -1,
false);
298 root[
"brightness"] =
add_property_json(
"Brightness", brightness.GetValue(requested_frame),
"float",
"", brightness.Contains(requested_point), brightness.GetCount(), -1.0, 1.0, brightness.GetClosestPoint(requested_point).interpolation, brightness.GetClosestPoint(requested_point).co.X,
false);
299 root[
"contrast"] =
add_property_json(
"Contrast", contrast.GetValue(requested_frame),
"float",
"", contrast.Contains(requested_point), contrast.GetCount(), 0, 20, contrast.GetClosestPoint(requested_point).interpolation, contrast.GetClosestPoint(requested_point).co.X,
false);
302 return root.toStyledString();
This class reads a special chunk-formatted file, which can be easily shared in a distributed environm...
Json::Value JsonValue()
Generate Json::JsonValue for this object.
bool replace_image
Replace the frame image with a grayscale image representing the mask. Great for debugging a mask...
tr1::shared_ptr< Frame > GetFrame(tr1::shared_ptr< Frame > frame, long int frame_number)
This method is required for all derived classes of EffectBase, and returns a modified openshot::Frame...
float End()
Get end position (in seconds) of clip (trim end of video)
A Point is the basic building block of a key-frame curve.
virtual void Close()=0
Close the reader (and any resources it was consuming)
This abstract class is the base class, used by all readers in libopenshot.
int Layer()
Get layer of clip on timeline (lower number is covered by higher numbers)
Exception when a reader is closed, and a frame is requested.
string class_name
The class name of the effect.
virtual Json::Value JsonValue()=0
Generate Json::JsonValue for this object.
bool has_audio
Determines if this effect manipulates the audio of a frame.
This class uses the ImageMagick++ libraries, to open image files, and return openshot::Frame objects ...
This class uses the FFmpeg libraries, to open video files and audio files, and return openshot::Frame...
Keyframe contrast
Contrast keyframe to control the hardness of the wipe effect / mask.
Json::Value add_property_choice_json(string name, int value, int selected_value)
Generate JSON choice for a property (dropdown properties)
Json::Value add_property_json(string name, float value, string type, string memo, bool contains_point, int number_of_points, float min_value, float max_value, InterpolationType intepolation, int closest_point_x, bool readonly)
Generate JSON for a property.
Exception for files that can not be found or opened.
string Id()
Get basic properties.
float Position()
Get position on timeline (in seconds)
string Json()
Get and Set JSON methods.
string name
The name of the effect.
string description
The description of this effect and what it does.
bool has_single_image
Determines if this file only contains a single image.
virtual Json::Value JsonValue()=0
Generate Json::JsonValue for this object.
virtual void SetJsonValue(Json::Value root)=0
Load Json::JsonValue into this object.
ChunkVersion
This enumeration allows the user to choose which version of the chunk they would like (low...
virtual void SetJsonValue(Json::Value root)=0
Load Json::JsonValue into this object.
string PropertiesJSON(long int requested_frame)
Mask()
Blank constructor, useful when using Json to load the effect properties.
ReaderInfo info
Information about the current media file.
This namespace is the default namespace for all code in the openshot library.
virtual tr1::shared_ptr< Frame > GetFrame(long int number)=0
void SetJsonValue(Json::Value root)
Load Json::JsonValue into this object.
Keyframe brightness
Brightness keyframe to control the wipe / mask effect. A constant value here will prevent animation...
bool has_video
Determines if this effect manipulates the image of a frame.
Exception for invalid JSON.
void SetJson(string value)
Load JSON string into this object.
This class uses the Qt library, to open image files, and return openshot::Frame objects containing th...
A Keyframe is a collection of Point instances, which is used to vary a number or property over time...
float Duration()
Get the length of this clip (in seconds)
Constant curves jump from their previous position to a new one (with no interpolation).
float Start()
Get start position (in seconds) of clip (trim start of video)
virtual void Open()=0
Open the reader (and start consuming resources, such as images or video files)
EffectInfoStruct info
Information about the current effect.
virtual bool IsOpen()=0
A thread safe version of GetFrame.